How to place the minimum value of a 3*3 matrix at center of the matrix.?

1 view (last 30 days)
aditya sahu on 7 Sep 2017
Commented: aditya sahu on 8 Sep 2017
Suppose a matrix x= 512*512 elements. How to select 3*3 matrix and the smallest element should be at the center position. i.e suppose the matrix is x1=
56 57 90
98 79 49
20 30 39
In the above 3*3 matrix as 20 is smaller compared to all so 20 and 79 position should be interchanged. let the above matrix is first 3*3 sub matrix of 512*512 matrix, then how to select the next 3*3 matrix and so on..

Andrei Bobrov on 7 Sep 2017
Edited: Andrei Bobrov on 8 Sep 2017
Let A - your array and we use Image Processing Toolbox :
out = imerode(A,ones(3));
[ii,jj] = ndgrid(ceil((1:size(A,1))/3),ceil((1:size(A,2))/3));
[~,~,c] = unique([ii(:),jj(:)],'rows');
for kk = 1:max(c)
t = kk == c;
k = A(t);
[~,n] = min(k(:));
nn = min(numel(k),5);
k([nn,n]) = k([n,nn]);
A(t) = k;
end
aditya sahu on 8 Sep 2017
Actually it is non recursive..and is applied to an spatial domian.

Stephen on 7 Sep 2017
Edited: Stephen on 7 Sep 2017
This is easy with linear indexing:
>> X = [56,57,90;98,79,49;20,30,39]
X =
56 57 90
98 79 49
20 30 39
>> [~,idx] = min(X(:));
>> X([idx,5]) = X([5,idx])
X =
56 57 90
98 20 49
79 30 39
Put this inside a function, and then use blockproc to call it for each 3x3 submatrix inside matrix A (untested):
function X = swapmin(S)
X = S.data;
[~,idx] = min(X(:));
X([idx,5]) = X([5,idx]);
end
and calling:
B = blockproc(A,[3,3],@swapmin)
Stephen on 7 Sep 2017
"and it is not working too."
It works for me:
>> A = randi(9,6,6)
A =
8 3 9 8 7 7
9 5 5 9 7 1
2 9 8 6 7 3
9 9 2 1 4 1
6 2 4 8 6 1
1 9 9 9 2 8
>> blockproc(A,[3,3],@swapmin)
ans =
8 3 9 8 7 7
9 2 5 9 1 7
5 9 8 6 7 3
9 9 2 6 4 1
6 1 4 8 1 1
2 9 9 9 2 8
As you can see, the center of each 3x3 block is now the minimum value, which is what your question requested.