Find Max Delta of Sliding 3x3 Window Over Matrix

3 ビュー (過去 30 日間)
Paul Safier
Paul Safier 2025 年 1 月 15 日
コメント済み: Paul Safier 2025 年 1 月 16 日
I have the code below to find the max delta between a point and its 8 neighbors in a sliding 3x3 window. I do this for the whole matrix input, A. This works fine and correct, but I am wondering if this can be accomplished with several uses of conv2 instead of the imerode/imdilation calls. The computation I'm doing is depicted in the attached image.
% This method works fine...
A = magic(3); % Test case
% This finds the max diff
% between a pixel and its 8 neighbors.
drMin = min(A(:)); drMax = max(A(:)); % Phantom (padding) pts outside of domain are assumed the avg.
padPt = mean([drMin drMax]); % Value to use for padding.
tmp1 = padarray(A,1,padPt,'both'); tmp2 = padarray(tmp1',1,padPt,'both'); Apad = tmp2'; % Pad matrix.
maxApad = imdilate(Apad,ones(3)) - Apad; % Local max minus the map. Delta from each pt to max neighbor.
minApad = imerode(Apad,ones(3)) - Apad; % Local min minus the map. Delta from each pt to min neighbor.
tmp(:,:,1) = abs(maxApad); tmp(:,:,2) = abs(minApad);
Ctmp = max(tmp,[],3); % Largest of the two gives the max delta from each point to its neighbors!
C = Ctmp(2:end-1,2:end-1); % Remove padding...
The expected result for the magic(3) input is:
7 7 5
6 4 6
5 7 7
I have tried with the following code, but it's clearly off.
A = magic(3);
arrayTot = zeros(3,3,8);
kernel = zeros([9 1]); kernel(5) = 1;
for k = 1:9
if k ~=5
kernel(k) = -1;
k1 = kernel;
k1 = reshape(k1,[3 3]);
tmp = conv2(A,k1,'same');
arrayTot(:,:,k) = abs(tmp);
kernel = zeros([9 1]); kernel(5) = 1;
end
end
tst = max(arrayTot,[],3)
Any advice would be appreciated. Thanks.

採用された回答

Sandeep Mishra
Sandeep Mishra 2025 年 1 月 16 日
Hi Paul,
You can use the MATLAB ‘conv2’ function to compute the Max-Delta of Sliding 3x3 Window by subtracting the center pixel with all 8 neighbours and taking the absolute difference.
Using an appropriate kernel can be helpful while dealing with the ‘conv2’ function, the following kernels can be used for the calculation:
% Kernels of neighbours are as follows: Right, Left, Up, Down, Top-Left, Top-Right, Bottom-Left, Bottom-Right
kernels = {
[0 0 0; 0 -1 1; 0 0 0],
[0 0 0; 1 -1 0; 0 0 0],
[0 1 0; 0 -1 0; 0 0 0],
[0 0 0; 0 -1 0; 0 1 0],
[1 0 0; 0 -1 0; 0 0 0],
[0 0 1; 0 -1 0; 0 0 0],
[0 0 0; 0 -1 0; 1 0 0],
[0 0 0; 0 -1 0; 0 0 1]
};
To handle edge cases and ensure accurate convolution, you can add the padding to the input matrix as follows:
A = magic(3)
A = 3×3
8 1 6 3 5 7 4 9 2
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
padPt = mean([min(A(:)), max(A(:))]);
% Pad the matrix with mean value
Apad = padarray(A, [1, 1], padPt, 'both');
Refer to the following example code snippet to apply Convolution to compute differences and obtain Max-Delta result:
diffs = zeros([size(Apad), 8]);
% Apply each kernel with conv2 and store the absolute difference
for k = 1:8
diffs(:,:,k) = abs(conv2(Apad, kernels{k}, 'same'));
end
% Using the maximum difference across all 8 neighbors
Ctmp = max(diffs, [], 3);
% Output after removing padding
res = Ctmp(2:end-1, 2:end-1)
res = 3×3
7 7 5 6 4 6 5 7 7
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Refer to the following MathWorks Documentation to learn more about ‘conv2’ function: https://www.mathworks.com/help/releases/R2024a/matlab/ref/conv2.html
I hope this helps you in resolving your query.
  1 件のコメント
Paul Safier
Paul Safier 2025 年 1 月 16 日
Thanks. I see the only difference between my code and yours was the padding. That made the difference!

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

その他の回答 (0 件)

製品


リリース

R2024a

Community Treasure Hunt

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

Start Hunting!

Translated by