Spaces:
Sleeping
Sleeping
| 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() |