필터 지우기
필터 지우기

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 CenterFile Exchange에서 Smoothing에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by