How to smooth surf?

145 Ansichten (letzte 30 Tage)
Alexandra Roxana
Alexandra Roxana am 30 Okt. 2022
Kommentiert: Lorenzo Melito am 3 Jan. 2024
I'm having a surface plot with many spikes. I was wondering what I can do to smooth it. interp2 might be a solution, I guess, but I'm having problems with the dimensions. Here is a part of the program:
a=0;
b=2;
c=0;
d=4;
M=40;
N=60;
hx=(b-a)/(M+1);
hy=(d-c)/(N+1);
alpha=inv(A)*L;
sol=zeros((M+2),(N+2));
for k=1:N*M
i=rem(k,M);
if i==0
i=M;
end
j=(k-i)/M+1;
newsol(i,j)=alpha(k);
end
sol(2:M+1,2:N+1)=newsol;
[X,Y]=meshgrid(a:hx:b,c:hy:d);
C = 1 + (X <= 0.25 | X >= 1.75);
surf(X,Y,sol',C);
colormap([1 0 0; 0 0 1]);
hold on
plot(0,0,'ko','MarkerSize',10,'MarkerFaceColor','black')
text(0,0,'(0,0)','Fontsize',20,'Color','k', 'Horiz','left','Vert','top')
plot(2,0,'k>','MarkerSize',10,'MarkerFaceColor','black')
text(2,0,'x_1','Fontsize',20,'Color','k', 'Horiz','left','Vert','top')
plot(0,4,'k<','MarkerSize',10,'MarkerFaceColor','black')
text(0,4,'x_2','Fontsize',20,'Color','k', 'Horiz','left','Vert','top')
xlabel('cm')
ylabel('cm')
zlabel('longitudinal fluid velocity (cm/s)')
  2 Kommentare
KALYAN ACHARJYA
KALYAN ACHARJYA am 30 Okt. 2022
A not defined?
Alexandra Roxana
Alexandra Roxana am 30 Okt. 2022
Bearbeitet: Alexandra Roxana am 30 Okt. 2022
I wouldn't want to post the entire program, I put these parts of the program for the dimensions. I can post an image though:

Melden Sie sich an, um zu kommentieren.

Antworten (1)

John D'Errico
John D'Errico am 30 Okt. 2022
Bearbeitet: John D'Errico am 30 Okt. 2022
interp2 does NO smoothing. It is NOT designed to smooth anything, and would NOT be appropriate, because interpolation does not change any of your data.
And all you post is code that nobody can execute. So helping you is difficult. If you really want help, then make it easy to get help. All we see is a picture, with no data provided.
The simplest way to perform a 2-dimensional smoothing operation in MATLAB is to use conv2. But you need to be careful around the edges, so there is a fix. Since you provide no data at all, I'll make something up.
[X,Y] = meshgrid(1:100);
Z = sin((2*X-3*Y)/75) + randn(size(X))/10;
surf(Z)
As I said, the simple idea is to use a convolution in 2-d, with a Gaussian smoothing kernel. That will blur out the noise, and if the noise is random, then a blur will be good, as long as the signal in your surface is slowly varying. But you need to consider what happens at the edges. conv2 will effectively insert zeros outside of the array. And that will cause a bias in the results around the borders.
[xk,yk] = meshgrid(-5:5);
K = exp(-(xk.^2 + yk.^2)/10); K = K/sum(K(:));
surf(K)
The smoothing kernel I'll use is a simple truncated 2-d Gaussian shape, then rescaled to sum to 1. The size of that smoothing kernel is a factor, since a larger (wider) kernel would do more smoothing.
Now we can use this to perform a blurring smooth in the array Z. But if I just use conv2 directly with that kernel, maintining the same size array. we have a problem.
Zhat1 = conv2(Z,K,'same');
surf(Zhat1)
As you can see, there is a band around the edges that is clearly biased towards zero. We can fix that as I show below.
Zhat2 = conv2(Z,K,'same')./conv2(ones(size(Z)),K,'same');
surf(Zhat2)
As you can see, the result is much smoother now. Not perfect because the original array was pretty well contaminated with noise, but it is still smooth out to the edges of the array, with no biased band around the edge.
You can use other schemes of course, perhaps based on median filters. I could think of many ways. In fact, you could even download my own gridft from the file exchange, which can smooth very nicely.
  1 Kommentar
Lorenzo Melito
Lorenzo Melito am 3 Jan. 2024
@John D'Errico, fantastic answer! Thanks a lot for the very informative process description!

Melden Sie sich an, um zu kommentieren.

Produkte


Version

R2017a

Community Treasure Hunt

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

Start Hunting!

Translated by