why does conv2 increase z height?
7 ビュー (過去 30 日間)
古いコメントを表示
I want to smooth a jagged 3D plot and I thought using
blurredImage = conv2(data, ones(15), 'same');
would help but the conv2 function seems to add unwanted height to the plot? Now I could manually set the axis ticks but surely there's a cause?
If not, how do I smooth 3D data?
0 件のコメント
回答 (2 件)
Bruno Luong
2023 年 8 月 15 日
Properly blurring without boundary dropdown artefact:
K = ones(15);
blurredImage = conv2(data, K, 'same') ./ conv2(ones(size(data)), K, 'same');
6 件のコメント
Bruno Luong
2023 年 8 月 15 日
編集済み: Bruno Luong
2023 年 8 月 15 日
It's expected and totally normal. The whole purpose of conv2 is to average out the data thus the variation and the amplitude of z reduced a little.
Bruno Luong
2023 年 8 月 15 日
The same example using surf to see how much z reduce
data = peaks(200) + 10;
K = ones(15);
blurredImage_2 = conv2(data, K, 'same') ./ conv2(ones(size(data)), K, 'same');
figure; surf(data, 'edgecolor', 'none'); title('original'); colorbar; climorg = clim; zlimorg = zlim;
figure; surf(blurredImage_2, 'edgecolor', 'none'); title('normalize with conv2(ones...)'); colorbar; clim(climorg); zlim(zlimorg)
John D'Errico
2023 年 8 月 15 日
編集済み: John D'Errico
2023 年 8 月 15 日
Easier to just see what is happening with a 1-d problem. First, some data.
t = linspace(0,10,200);
y0 = sin(t); % about as simple as you can get.
plot(t,y0)
First, what happens with just a vector of ones?
K1 = ones(1,20);
y1 = conv(y0,K1,'same');
plot(t,y0,'b',t,y1,'r')
legend('Original curve','Conv-ed curve, with just ones')
Do you see the red curve has a MUCH greater amplitude? It has very much the same shape, but it is around 20 times as high. But why is that?
At any point, we are forming the sum of 20 elements from y0. Just adding them up. Do you see this is how a convolution works? So then it MUST be a larger number than the original curve.
Instead, you can scale the convolution kernel, so it sums to 1.
K2 = K1/sum(K1);
Now, when we form the convolution, it will perform better. But still it is not going to repreoduce the original curve. In fact, I expect it will flatten things out a bit.
y2 = conv(y0,K2,'same');
plot(t,y0,'b',t,y2,'r')
grid on
legend('Original curve','Conv-ed curve, with normalized Kernel')
(Ignore the crap at the ends, since the convolution is not going to be correct there. I could have used the 'valid' option for conv, but that would have screwed around with the vector lengths, and I am too lazy to deal with it.) So now the convolution has compressed things, but just a bit. At the peak of the original curve, we are forming a sum where all but one of the elements in that original vector were less than 1. So how can the sum ever be exactly the same?
We can see this by doing the convolution in a symbolic form.
syms t T
% A unit hat function to act as the convolution kernel
hat = @(Ti) heaviside(Ti + 1/2) - heaviside(Ti - 1/2);
First, note that the integral of hat is 1. This is comparable to the normalization of the discrete convolution kernel to sum to 1.
int(hat(t),-inf,inf)
The symbolic convolution is easy, and it has an easy to understand form.
conved_sin = int(sin(t)*hat(T-t),-inf,inf)
Plot the result.
fplot(@sin)
hold on
fplot(conved_sin)
hold off
grid on
legend('Original curve','Conv-ed curve, with normalized Kernel')
Again, it looks just like a sine wave, but the amplitude is reduced. In fact, we can predict the reduction in the amplitude, as 2*sin(1/2)
2*sin(1/2)
So we expect here to see a 4.11% reduction in amplitude. That is, still a sine wave, but now a 95% sine wave.) The reduction we saw from conv mirrors that pretty closely, though it would not be exactly the same, since conv used a 20 point convolution kernel. Remember that conv is a NUMERICAL tool. It is NOT exactly the same, but the difference is a minor one as I would expect.
The 2-d case is fundamentally the same. Just more difficult to visualize.
0 件のコメント
参考
カテゴリ
Help Center および File Exchange で Orange についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!