How to smooth the curve indicated on the image?

4 ビュー (過去 30 日間)
Rhandrey Maestri
Rhandrey Maestri 2022 年 11 月 11 日
回答済み: Image Analyst 2022 年 11 月 30 日
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

採用された回答

Mathieu NOE
Mathieu NOE 2022 年 11 月 14 日
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 件のコメント
Rhandrey Maestri
Rhandrey Maestri 2022 年 11 月 18 日
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 2022 年 11 月 18 日
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

サインインしてコメントする。

その他の回答 (1 件)

Image Analyst
Image Analyst 2022 年 11 月 30 日
You can use a Savitzky-Golay filter, like the attached demo.

カテゴリ

Help Center および File ExchangeSmoothing についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by