How to smooth the curve indicated on the image?
5 views (last 30 days)
Show older comments
Rhandrey Maestri
on 11 Nov 2022
Answered: Image Analyst
on 30 Nov 2022
Hi, Can anyone help me in smoothing this data ?
I have included the coordinates of the left and right side in txt.
I´d really appreciate,
Thanks
0 Comments
Accepted Answer
Mathieu NOE
on 14 Nov 2022
hello
you can try this
adjust the amount of smoothing (and window type ) in this line :
rs = smoothdata(r_new,'gaussian',61);
full code :
xL = readmatrix('left.txt');
yL = (1:numel(xL))';
xR = readmatrix('right.txt');
yR = (1:numel(xR))';
xR = xR(end:-1:1); % flip upside down
yR = yR(end:-1:1); % flip upside down
% remove NaN's and concatenate left and right coordinates
x= [xL;xR];
idx = isnan(x);
x(idx) = [];
y= [yL;yR];
y(idx) = [];
% %% method 1 using smoothn (https://fr.mathworks.com/matlabcentral/fileexchange/25634-smoothn/?requestedDomain=)
% z = smoothn({x,y},1e3);
% figure(1),plot(x,y,'r.',z{1},z{2},'k','linewidth',2)
%% method 2
centroid_x = mean(x);
centroid_y = mean(y);
[theta,r] = cart2pol(x-centroid_x,y-centroid_y);
% closing the circle
r(end+1) = r(1);
theta(end+1) = theta(1);
% sort theta in ascending order
[theta,ind] = sort(theta);
r = r(ind);
% remove duplicates
[theta,IA,IC] = unique(theta);
r = r(IA);
theta_new = linspace(min(theta),max(theta),1000);
r_new = interp1(theta,r,theta_new);
% smoothing
rs = smoothdata(r_new,'gaussian',61);
% convert to cartesian
[xn,yn] = pol2cart(theta_new,rs);
% add back centroid info
xn = xn + centroid_x;
yn = yn + centroid_y;
%% XY plot
figure(2),plot(x,y,'b*',xn,yn,'r');
legend('raw','smoothed');
5 Comments
Mathieu NOE
on 18 Nov 2022
hello again
so I tweaked a bit the code
for the small waves at the top I cannot make them bigger are they are , hope it's good enough now
xL = readmatrix('left.txt');
yL = (1:numel(xL))';
% remove NaN for left data
idx = isnan(xL);
xL(idx) = [];
yL(idx) = [];
xR = readmatrix('right.txt');
yR = (1:numel(xR))';
% remove NaN for left data
idx = isnan(xR);
xR(idx) = [];
yR(idx) = [];
% smooth the X data with "smart" function below
alpha_max = 0.999;
para1 = 220; % samples
para2 = 55; % samples
outL = smart_smooth(xL,para1,para2,alpha_max);
outR = smart_smooth(xR,para1,para2,alpha_max);
% concatenate left and right coordinates
xR = xR(end:-1:1); % flip upside down
yR = yR(end:-1:1); % flip upside down
outR = outR(end:-1:1); % flip upside down
x= [xL;xR;xL(1)]; % close the curve
y= [yL;yR;yL(1)]; % close the curve
xs= [outL;outR;outL(1)]; % close the curve
plot(x,y,'b',xs,y,'r');
%%%%%%%%%%%%%%%%function%%%%%%%%%%%%%%%%
function out = smart_smooth(in,para1,para2,alpha_max)
% "smart filter" : simple first order low pass filter (2 stages in series = 2nd order filter),
% the smoothing factor varies with time (low at the beginning and end , then
% increases in the middle section
%% main loop
out = zeros(size(in));
out(1) = in(1);
samples = numel(in);
for ci = 2:samples
if ci <= para1 % start time to increase alpha
alpha = alpha_max*ci/para1;
elseif ci >= samples-para2 % start time to decrease alpha
alpha = alpha_max*(1-ci/samples);
else
alpha = alpha_max;
end
% first order low pass IIR filter recursion
out(ci) = alpha.*out(ci-1) + (1-alpha).*in(ci);
end
end
More Answers (1)
Image Analyst
on 30 Nov 2022
You can use a Savitzky-Golay filter, like the attached demo.
0 Comments
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!