필터 지우기
필터 지우기

Trying to pattern match 5 repetitions in 2-d array

조회 수: 1 (최근 30일)
Scott
Scott 2014년 9월 28일
답변: Anand 2014년 9월 29일
I have the following array and I need to find and transpose into a results array each time 5 consecutive numbers match in rows or columns or both. 19x19 array only options -1,0,1 Can anyone help ?
1 1 1 -1 -1 -1 1 1 -1 -1 -1 -1 1 -1 -1 -1 -1 -1 0
1 -1 -1 1 1 -1 -1 -1 -1 -1 1 -1 -1 1 -1 -1 -1 1 0
1 1 1 1 -1 1 -1 -1 -1 -1 1 -1 1 1 1 1 1 1 0
-1 -1 -1 1 1 -1 1 1 -1 -1 1 -1 -1 1 1 -1 1 -1 0
-1 -1 1 -1 1 1 -1 1 1 1 -1 -1 -1 1 1 1 -1 1 1
-1 1 -1 -1 1 1 0 -1 -1 1 -1 1 -1 1 -1 1 -1 1 0
1 -1 1 1 -1 -1 -1 -1 1 -1 1 -1 -1 1 1 -1 -1 -1 1
1 1 0 -1 -1 0 -1 -1 1 -1 -1 1 1 -1 1 -1 1 1 0
-1 1 1 1 1 -1 -1 -1 0 1 1 1 1 1 -1 -1 1 -1 0
1 1 1 1 1 -1 1 -1 1 -1 1 -1 1 1 -1 1 -1 -1 1
0 -1 1 1 1 1 0 0 -1 1 1 1 -1 0 1 0 1 -1 1
-1 -1 1 -1 -1 1 1 1 -1 -1 -1 1 1 1 -1 -1 1 1 0
1 -1 -1 -1 1 1 1 1 -1 1 -1 -1 -1 -1 1 -1 1 -1 0
1 1 1 -1 -1 1 -1 1 1 1 -1 -1 1 1 1 1 -1 1 0
-1 -1 1 1 1 -1 1 1 1 -1 1 1 1 -1 -1 1 -1 -1 1
1 1 -1 1 -1 0 -1 -1 -1 -1 1 -1 -1 1 -1 1 -1 -1 1
-1 -1 1 -1 -1 1 1 1 -1 1 -1 -1 -1 1 1 -1 -1 1 1
1 -1 1 -1 -1 0 1 -1 -1 -1 -1 1 -1 -1 0 1 1 1 1
0 1 0 1 1 1 0 1 0 1 1 0 0 0 0 0 1 1 -1
ideally my output should be (r)ow, (c)olumn or (b)oth to mark where the pattern match starts
  댓글 수: 2
the cyclist
the cyclist 2014년 9월 28일
For the input matrix shown, what is the output you expect?
Also, you might want to consider putting up a smaller example (e.g. looking for 2 matches in a 5x5 matrix), just to make it easier to visualize what you are looking for.
That being said, an important component of the solution will likely be the diff() function, which you can apply in either dimension.
Image Analyst
Image Analyst 2014년 9월 28일
I'm not sure what "find and transpose into a results array" means exactly. What goes into the results array? The row and column where that pattern starts?

댓글을 달려면 로그인하십시오.

답변 (2개)

Image Analyst
Image Analyst 2014년 9월 28일
If you have the Image Processing Toolbox, use normxcorr2() which is meant for this:
m=[...
1 1 1 -1 -1 -1 1 1 -1 -1 -1 -1 1 -1 -1 -1 -1 -1 0
1 -1 -1 1 1 -1 -1 -1 -1 -1 1 -1 -1 1 -1 -1 -1 1 0
1 1 1 1 -1 1 -1 -1 -1 -1 1 -1 1 1 1 1 1 1 0
-1 -1 -1 1 1 -1 1 1 -1 -1 1 -1 -1 1 1 -1 1 -1 0
-1 -1 1 -1 1 1 -1 1 1 1 -1 -1 -1 1 1 1 -1 1 1
-1 1 -1 -1 1 1 0 -1 -1 1 -1 1 -1 1 -1 1 -1 1 0
1 -1 1 1 -1 -1 -1 -1 1 -1 1 -1 -1 1 1 -1 -1 -1 1
1 1 0 -1 -1 0 -1 -1 1 -1 -1 1 1 -1 1 -1 1 1 0
-1 1 1 1 1 -1 -1 -1 0 1 1 1 1 1 -1 -1 1 -1 0
1 1 1 1 1 -1 1 -1 1 -1 1 -1 1 1 -1 1 -1 -1 1
0 -1 1 1 1 1 0 0 -1 1 1 1 -1 0 1 0 1 -1 1
-1 -1 1 -1 -1 1 1 1 -1 -1 -1 1 1 1 -1 -1 1 1 0
1 -1 -1 -1 1 1 1 1 -1 1 -1 -1 -1 -1 1 -1 1 -1 0
1 1 1 -1 -1 1 -1 1 1 1 -1 -1 1 1 1 1 -1 1 0
-1 -1 1 1 1 -1 1 1 1 -1 1 1 1 -1 -1 1 -1 -1 1
1 1 -1 1 -1 0 -1 -1 -1 -1 1 -1 -1 1 -1 1 -1 -1 1
-1 -1 1 -1 -1 1 1 1 -1 1 -1 -1 -1 1 1 -1 -1 1 1
1 -1 1 -1 -1 0 1 -1 -1 -1 -1 1 -1 -1 0 1 1 1 1
0 1 0 1 1 1 0 1 0 1 1 0 0 0 0 0 1 1 -1]
% Define pattern/template to look for.
template = [-1, 0, 1];
out = normxcorr2(template, m)
% Clip off left side to make it be the same size as the original.
out = out(:, length(template):end);
% Display rows and columns of left most index match.
[rows, columns] = find(out >= 0.99)
In the command window:
rows =
18
9
11
18
columns =
5
8
13
14

Anand
Anand 2014년 9월 29일
Sounds like this is what you're looking for:
m = [1 1 1 -1 -1 -1 1 1 -1 -1 -1 -1 1 -1 -1 -1 -1 -1 0
1 -1 -1 1 1 -1 -1 -1 -1 -1 1 -1 -1 1 -1 -1 -1 1 0
1 1 1 1 -1 1 -1 -1 -1 -1 1 -1 1 1 1 1 1 1 0
-1 -1 -1 1 1 -1 1 1 -1 -1 1 -1 -1 1 1 -1 1 -1 0
-1 -1 1 -1 1 1 -1 1 1 1 -1 -1 -1 1 1 1 -1 1 1
-1 1 -1 -1 1 1 0 -1 -1 1 -1 1 -1 1 -1 1 -1 1 0
1 -1 1 1 -1 -1 -1 -1 1 -1 1 -1 -1 1 1 -1 -1 -1 1
1 1 0 -1 -1 0 -1 -1 1 -1 -1 1 1 -1 1 -1 1 1 0
-1 1 1 1 1 -1 -1 -1 0 1 1 1 1 1 -1 -1 1 -1 0
1 1 1 1 1 -1 1 -1 1 -1 1 -1 1 1 -1 1 -1 -1 1
0 -1 1 1 1 1 0 0 -1 1 1 1 -1 0 1 0 1 -1 1
-1 -1 1 -1 -1 1 1 1 -1 -1 -1 1 1 1 -1 -1 1 1 0
1 -1 -1 -1 1 1 1 1 -1 1 -1 -1 -1 -1 1 -1 1 -1 0
1 1 1 -1 -1 1 -1 1 1 1 -1 -1 1 1 1 1 -1 1 0
-1 -1 1 1 1 -1 1 1 1 -1 1 1 1 -1 -1 1 -1 -1 1
1 1 -1 1 -1 0 -1 -1 -1 -1 1 -1 -1 1 -1 1 -1 -1 1
-1 -1 1 -1 -1 1 1 1 -1 1 -1 -1 -1 1 1 -1 -1 1 1
1 -1 1 -1 -1 0 1 -1 -1 -1 -1 1 -1 -1 0 1 1 1 1
0 1 0 1 1 1 0 1 0 1 1 0 0 0 0 0 1 1 -1];
found = false(size(m));
for i = 1 : size(m,1)-4
for j = 1 : size(m,2)-4
% tag if current array element is equal to next 4 along row or column
found(i,j) = all(m(i,j:j+4)==m(i,j)) || all(m(i:i+4,j)==m(i,j));
end
end
[r,c] = find(found);
>> [r,c]
ans =
10 1
2 6
6 8
9 10
1 12
3 13
1 14
2 14
3 14
Just loop over the elements of the array and tag the elements that are equal to the next 4 elements (row or column). There's probably ways to vectorize this, but for your array size I don't think there's a need to.

카테고리

Help CenterFile Exchange에서 Matrices and Arrays에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by