How to get a smooth boundary between clusters?
12 views (last 30 days)
Show older comments
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 Comment
Garmit Pant
on 30 Jan 2024
Hello RoboTomo
Can you please share the code for boundary detection and smoothing that you are using?
Accepted Answer
Image Analyst
on 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 Comments
More Answers (2)
Garmit Pant
on 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:
- “smoothdata” function: https://www.mathworks.com/help/matlab/ref/smoothdata.html
- “smooth” function: https://www.mathworks.com/help/curvefit/smooth.html
- “writetable” function: https://www.mathworks.com/help/matlab/ref/writetable.html
I hope you find the above explanation and suggestions useful!
See Also
Categories
Find more on Smoothing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!