How to smooth the curve indicated on the image?

5 views (last 30 days)
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

Accepted Answer

Mathieu NOE
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
Rhandrey Maestri
Rhandrey Maestri on 18 Nov 2022
Hi, your second solution is very good.
In this image I show in black line what I would like even more if possible (but with the curves more soft as in your solution). There is also a small wave on the top before getting continuous.
Mathieu NOE
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

Sign in to comment.

More Answers (1)

Image Analyst
Image Analyst on 30 Nov 2022
You can use a Savitzky-Golay filter, like the attached demo.

Community Treasure Hunt

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

Start Hunting!