How to get a smooth boundary between clusters?

73 Ansichten (letzte 30 Tage)
RoboTomo
RoboTomo am 22 Jan. 2024
Bearbeitet: RoboTomo am 8 Apr. 2024 um 9:53
So for my dataset I am doing K-means clustering (Fig.1) with smoothing (Fig.2). Then I would like to define boundaries between different clusters and package them into a .csv file so I can import them into Fusion360 for CAM machining. Currently I am doing boundary detection based on "KDTreeSearcher" and "knnsearch" but results are not perfect (Fig.3). First problem is that I have double boundaries for each cluster (this I can fix somehow) and second one is that I would like more smooth lines / boundaries between clusters:
I am attaching my cluster dataset with xyz position of points and smoothed cluster data. I can also attach my existing code for boundaries detection and smoothing if necessary.
*Edit, thank you for all the answers and I apologize for my delayed response. I have now also added the sample Matlab program ("clustering forum") with my dataset.
  1 Kommentar
Garmit Pant
Garmit Pant am 30 Jan. 2024
Hello RoboTomo
Can you please share the code for boundary detection and smoothing that you are using?

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Image Analyst
Image Analyst am 1 Feb. 2024
I doubt you need to smooth the boundary. That would just give you as many coordinates as you had before and most likely more coordinates since you'd have to have extra points in between the grid points to make sure it was smooth. What I think you want (and I'm not even sure that is necessary to do before importation into your other software) is to reduce the number of points. So I think you may want the "minimum perimeter polygon" -- Google it. What this will do is to take long stretches like your roughly linear run of jaggies and replace that run with just two points - the endpoints of a line running through them. But in areas where there is a lot of change, like turning corners or tight curves, it will keep as many coordinates as it needs to follow the curve there.
See attached tutorial paper.
  6 Kommentare
RoboTomo
RoboTomo am 2 Apr. 2024 um 15:04
Bearbeitet: RoboTomo am 8 Apr. 2024 um 9:53
Thank you for your extensive comment. Yes, I am already facing with this smoothing problem as you mentioned at the end. When I initially run the K-means clustering with directions as input I get a lot of scattered data, which is correct, but is not suitable for my application, so I need to find a proper threshold criteria to reorganize the points. The same thing happens with boundaries - I can't export a zig-zag straight lines between boundary points but a nice curve. Will try again all of the methods provided in answers and give a feedback.
RoboTomo
RoboTomo am 8 Apr. 2024 um 9:52
With your help I have managed to better plot the boundaries and also smooth them, so thank you!
I have one bonus question if you'd be willing to give some suggestion. What would be the best way to plot a single boundary line between different clusters, or fit a new line between existing boundary lines? The result should look something like the red line below which is hand drawn.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (2)

Matt J
Matt J am 30 Jan. 2024
Once you've extracted the boundary points, you could use sgolayfilt to smooth them.
  1 Kommentar
RoboTomo
RoboTomo am 29 Mär. 2024 um 9:28
Thank you. I used the function, but did not get good results.

Melden Sie sich an, um zu kommentieren.


Garmit Pant
Garmit Pant am 1 Feb. 2024
Hello RoboTomo
From what I gather, you have a dataset and you have clustered the data points into 3 clusters using ‘kmeans” functions. You have also smoothed the data and found the boundaries between the clusters using ‘KDTreeSearcher” and “knnsearch”. Now you need to smooth the boundaries and store them in a CSV-file.
You can consider the following techniques to smooth the boundary points.
  • Smoothing the data using “smoothdata: Use the “smoothdata” function to smooth the single boundary points that you have extracted. Use “gaussian” smoothing method. The code snippet compares the effects of the “window” input argument. A smaller window size retains details while a larger window size produces smoother data.
% Sample data with a spike
x = linspace(0, 10, 100);
y = sin(x); % Adding random noise between x=4 and x=6
y_noisy = y + ((x > 4) & (x < 6)) .* (0.5 - rand(1,100));
smallWindowSize = 5; % Small Gaussian window size
y_smooth_small = smoothdata(y_noisy, 'gaussian', smallWindowSize);
% Smooth the data using a large Gaussian window
largeWindowSize = 21; % Large Gaussian window size
y_smooth_large = smoothdata(y_noisy, 'gaussian', largeWindowSize);
% Plot the results
figure;
plot(x, y_noisy, 'b', 'DisplayName', 'Noisy Data');
hold on;
plot(x, y_smooth_small, 'g--', 'DisplayName', 'Smoothed Data (Small Gaussian)');
plot(x, y_smooth_large, 'm--', 'DisplayName', 'Smoothed Data (Large Gaussian)');
legend;
title('Data Smoothing using smoothdata with Small vs Large Gaussian window');
xlabel('x');
ylabel('y');
  • Use the “smooth” function to smooth the data: The boundary extracted can also be smoothed using the Curve Fitting Toolbox function “smooth”. You can smooth the boundaries between different endpoints to get smoother boundaries. The function has multiple filters. The following code snippet shows how to smooth just a segment of the data.
x = (0:0.1:15)';
y = sin(x) + 0.5*(rand(size(x))-0.5);
y([90,110]) = 3;
% Define the segment to smooth
segmentIndices = (x >= 5) & (x <= 10);
% Smooth only the segment with the loess and rloess methods
yy1_segment = smooth(x(segmentIndices),y(segmentIndices),0.1,'loess');
yy2_segment = smooth(x(segmentIndices),y(segmentIndices),0.1,'rloess');
% Plot the original and smoothed data for the entire range
subplot(2,1,1)
plot(x,y,'b.',x(segmentIndices),yy1_segment,'r-')
set(gca,'YLim',[-1.5 3.5])
legend('Original data','Smoothed data using ''loess''',...
'Location','NW')
subplot(2,1,2)
plot(x,y,'b.',x(segmentIndices),yy2_segment,'r-')
set(gca,'YLim',[-1.5 3.5])
legend('Original data','Smoothed data using ''rloess''',...
'Location','NW')
To save the smoothed data to a CSV-file, you need to convert the data to a table and then write to the file using “writetable” function.
For further understanding on the methods mentioned above, you can refer to the following MATLAB Documentation:
  1. smoothdata” function: https://www.mathworks.com/help/matlab/ref/smoothdata.html
  2. smooth” function: https://www.mathworks.com/help/curvefit/smooth.html
  3. writetable” function: https://www.mathworks.com/help/matlab/ref/writetable.html
I hope you find the above explanation and suggestions useful!
  1 Kommentar
RoboTomo
RoboTomo am 29 Mär. 2024 um 9:27
Thank you for your answer. I did some testing, but did not get good results just like in sgolayfilt, so maybe I am doing something wrong. I attached the original code.

Melden Sie sich an, um zu kommentieren.

Produkte


Version

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by