line_models_sampling / line_models_sampling.py
jmartinezot's picture
Adding circular noise
164569e
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
import gradio as gr
from gradio.components import Slider, Number, Image, Dataframe
import matplotlib
matplotlib.use('Agg')
def generate_random_points_in_circle(center_x, center_y, radius, num_points):
angles = np.random.uniform(0, 2 * np.pi, num_points)
radii = np.sqrt(np.random.uniform(0, radius**2, num_points))
x_values = center_x + radii * np.cos(angles)
y_values = center_y + radii * np.sin(angles)
points = np.column_stack((x_values, y_values))
return points
def generate_random_points_in_line_between_bounds_and_with_noise(slope, intercept, mean, std, num_points, x_min, x_max):
x_values = np.linspace(x_min, x_max, num_points)
noise = np.random.normal(mean, std, num_points)
y_values = slope * x_values + intercept + noise
points = np.column_stack((x_values, y_values))
return points
def generate_all_points(line_num_points, circle_num_points, center_x, center_y, radius, slope, intercept, mean, std, x_min, x_max):
circle_points = generate_random_points_in_circle(center_x, center_y, radius, circle_num_points)
line_points = generate_random_points_in_line_between_bounds_and_with_noise(slope, intercept, mean, std, line_num_points, x_min, x_max)
all_points = np.concatenate((circle_points, line_points), axis=0)
return line_points, circle_points, all_points
def create_points_plot(line_points, circle_points):
fig, ax = plt.subplots()
x_values = line_points[:, 0]
y_values = line_points[:, 1]
ax.scatter(x_values, y_values, alpha=0.2, color="blue")
ax.scatter(circle_points[:, 0], circle_points[:, 1], alpha=0.2, color='red')
fig.canvas.draw()
img = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8)
img = img.reshape(fig.canvas.get_width_height()[::-1] + (3,))
plt.close(fig)
return img
def create_points_lines_plot(line_points, line_parameters):
fig, ax = plt.subplots()
x_values = line_points[:, 0]
y_values = line_points[:, 1]
ax.scatter(x_values, y_values, alpha=0.2)
for slope, intercept in line_parameters:
ax.plot(x_values, slope * x_values + intercept, alpha=0.5)
fig.canvas.draw()
img = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8)
img = img.reshape(fig.canvas.get_width_height()[::-1] + (3,))
plt.close(fig)
return img
def create_cluster_plot(line_parameters, labels, centroids):
fig, ax = plt.subplots()
ax.scatter(line_parameters[:, 0], line_parameters[:, 1], c=labels, cmap='viridis')
ax.set_xlabel('Slope')
ax.set_ylabel('Intercept')
fig.canvas.draw()
img = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8)
img = img.reshape(fig.canvas.get_width_height()[::-1] + (3,))
plt.close(fig)
return img
# Modify the compute_line_parameters function
def compute_line_parameters(num_iterations, all_points):
line_parameters = np.zeros((num_iterations, 2))
for i in range(num_iterations):
idx = np.random.choice(all_points.shape[0], 2, replace=False)
x1, y1 = all_points[idx[0], 0], all_points[idx[0], 1]
x2, y2 = all_points[idx[1], 0], all_points[idx[1], 1]
line_slope = (y2 - y1) / (x2 - x1)
line_intercept = y1 - line_slope * x1
line_parameters[i, 0] = line_slope
line_parameters[i, 1] = line_intercept
return line_parameters
def cluster_line_parameters(line_parameters, num_clusters, all_points, circle_points):
kmeans = KMeans(n_clusters=num_clusters)
kmeans.fit(line_parameters)
labels = kmeans.labels_
centroids = kmeans.cluster_centers_
counts = np.bincount(labels)
points_img = create_points_plot(all_points, circle_points)
points_lines_img = create_points_lines_plot(all_points, line_parameters)
cluster_img = create_cluster_plot(line_parameters, labels, centroids)
return labels, centroids, counts, points_img, points_lines_img, cluster_img
# Update the cluster_line_params function
def cluster_line_params(slope, intercept, mean, std, line_num_points, x_min, x_max, num_iterations, num_clusters, center_x, center_y, radius, circle_num_points, random_seed):
np.random.seed(random_seed)
num_iterations = int(num_iterations)
num_clusters = int(num_clusters)
line_points, circle_points, all_points = generate_all_points(line_num_points, circle_num_points, center_x, center_y, radius, slope, intercept, mean, std, x_min, x_max)
line_parameters = compute_line_parameters(num_iterations, all_points)
labels, centroids, counts, points_img, points_lines_img, cluster_img = cluster_line_parameters(line_parameters, num_clusters, all_points, circle_points)
centroids = np.c_[centroids, counts]
df = pd.DataFrame(centroids, columns=["Slope", "Intercept", "Count"])
return points_img, points_lines_img, cluster_img, df
# Define input and output components
inputs = [
Slider(minimum=-5.0, maximum=5.0, value=1.0, label="Line Slope"),
Slider(minimum=-10.0, maximum=10.0, value=0.0, label="Line Intercept"),
Slider(minimum=0.0, maximum=5.0, value=1.0, label="Line Error Mean"),
Slider(minimum=0.0, maximum=5.0, value=1.0, label="Line Error Standard Deviation"),
Number(value=100, precision=0, label="Number of Points Sampled from the Line"),
Number(value=-5, label="Minimum Value of x for Sampling"),
Number(value=5, label="Maximum Value of x for Sampling"),
Number(value=100, label="Number of Iterations for RANSAC-like Line Parameter Estimation"),
Number(value=3, label="Number of Clusters of Line Parameters"),
Number(value=0, label="X Value Center of the Circle"),
Number(value=0, label="Y Value Center of the Circle"),
Number(value=1, label="Radius of the Circle"),
Number(value=100, precision=0, label="Number of Points Sampled from the Circle"),
Number(value=0, precision=0, label="Random Seed")
]
outputs = [
Image(label="Points", type="pil"),
Image(label="Points and Lines", type="pil"),
Image(label="Clustering of the line parameters", type="pil"),
Dataframe(label="Centroids and Counts", type="pandas")
]
# Create the Gradio interface
interface = gr.Interface(
fn=cluster_line_params,
inputs=inputs,
# outputs=["numpy", "numpy", "image"],
outputs=outputs,
title="Line Parameter Clustering",
description="Cluster line parameters with Gaussian noise",
allow_flagging="never"
)
# Launch the interface
interface.launch()