How to look up a smaller array in a larger array while preserving shape
Mostrar comentarios más antiguos
I have a logical array. I want to look for a 2x2 "square" of 1's in this array, and return whether this square is present in this array or not.
LargeArray= [0,0,0,0;1,0,0,0;1,0,0,0;1,1,0,0;1,1,0,0;1,1,0,0;0,0,0,0;0,0,0,0]
FindArray= [1,1;1,1]
When I use ismember, I get the Large array as the answer, but I am looking to get the answer of whether the smaller FindArray is present in the LargeArray or not in True or False so I can use it to tag my data. Thanks!
Respuesta aceptada
Más respuestas (2)
Bruno Luong
el 26 de Nov. de 2022
Editada: Bruno Luong
el 26 de Nov. de 2022
Use convolution to detect matching
% I modified it to make example more interesting
LargeArray= [0,0,0,0;1,0,0,0;1,0,0,0;1,1,0,0;1,1,1,0;0,1,1,0;0,0,0,0;0,0,0,0]
FindArray= [1,1;1,1]
shiftfun = @(B) 2*B-1; % transform 0/1 respectively to -1/1
c = conv2(shiftfun(LargeArray),rot90(shiftfun(FindArray),2),'valid');
% Match (upper-left) indexes in LargeArray
[row,col] = find(c==numel(FindArray));
MatchIndex = table(row,col)
1 comentario
On case the pattern array contains only 1s, the code can be simplified in single-line
% I modified it to make example more interesting
LargeArray= [0,0,0,0;1,0,0,0;1,0,0,0;1,1,0,0;1,1,1,0;0,1,1,0;0,0,0,0;0,0,0,0]
FindArray= ones(2,2)
% Match (upper-left) indexes in LargeArray
[row,col] = find(conv2(LargeArray,FindArray,'valid')==numel(FindArray));
MatchIndex = table(row,col)
I'm going to demonstrate a couple ways you can do this using neighborhood operations. The case of a solid 2x2 nhood is a bit of a simplified case, but these can be extended to more general binary pattern matching. For these examples, I'm going to shamelessly steal Bruno's improved test array.
If you have IPT, you can use bwlookup().
LargeArray = [0,0,0,0; 1,0,0,0; 1,0,0,0; 1,1,0,0; 1,1,1,0; 0,1,1,0; 0,0,0,0; 0,0,0,0];
nhood = [1 1; 1 1]; % any 2x2 neighborhood
f = @(x) isequal(x,nhood); % function that describes matching behavior
lut = makelut(f,2); % create LUT for a 2x2 nhood
mk = bwlookup(LargeArray,lut) % logical map of matches
[r c] = find(mk) % convert logical mask to row,col subscripts
Alternatively, you can use basic linear filters.
LargeArray = [0,0,0,0; 1,0,0,0; 1,0,0,0; 1,1,0,0; 1,1,1,0; 0,1,1,0; 0,0,0,0; 0,0,0,0];
nhood = [1 1; 1 1]; % any 2x2 neighborhood pattern
seb = 2.^([1 3; 2 4]-1); % index weighting array
mk = imfilter(double(LargeArray),seb) == sum(sum(seb.*nhood)) % logical map of matches
[r c] = find(mk) % convert logical mask to row,col subscripts
Categorías
Más información sobre Matrices and Arrays en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!