Determine if there are 3 consecutive rows and columns in a list of subscripts
1 次查看(过去 30 天)
显示 更早的评论
I have a 28x2 matrix (see printout below) of subscript values (row, col) and I want to determine if there are 3 consecutive rows and then 3 connective columns coming stemming from a single reference point in the list of subscripts. From the example list below, the answer to this questions would be 'yes'. This is because the 3 consecutive rows are (44,13), (45,13), (46,13), and the 3 consecutive columns are (44,13), (44,14), (44,15). How would I execute this in matlab? I was thinking of using diff(A) to determine changes in subscript values but I am unsure exactly how. Sorry if this is confusing at all, wasn't sure how to explain my problem.
A =
43 15
44 13
44 14
44 15
44 16
45 12
45 13
45 14
45 15
45 16
46 12
46 13
46 14
46 15
46 16
47 12
47 13
47 14
48 11
48 12
48 13
49 11
49 12
49 13
50 11
50 12
50 13
0 个评论
采纳的回答
Matt J
2018-9-17
编辑:Matt J
2018-9-17
map=conv2( accumarray(A,1), ones(3),'same');
any3x3 = any(map(:))>=9
7 个评论
Guillaume
2018-9-17
Hum, the convolution looks for the pattern
[1 1 1
1 1 1
1 1 1]
which as far as I understood is not what was asked for and is a lot more restrictive. E.g, the code fails with:
A = [1 1; 1 2; 1 3; 2 1; 3 1]
And I'm not sure my answer matches what was asked for either. I understood that the 3 consecutive columns and 3 consecutive rows could be completely independent. Rereading the question, I think that the 3 consecutive rows and columns must intersect.
更多回答(1 个)
Guillaume
2018-9-17
One option:
hasconseccols = any(accummarray(A(:, 1), A(:, 2), [], @(v) ~isempty(strfind(sort(diff(v))', [ 1 1]))))
hasconsecrows = any(accummarray(A(:, 2), A(:, 1), [], @(v) ~isempty(strfind(sort(diff(v))', [ 1 1]))))
which basically, regroup together in a vector all the indices corresponding to a row/column respectively, sort that vector, take its diff and search for [1 1] which indicates at least 3 consecutive indices. If the search is not empty you have at least one row/column with 3 consecutive points.
Another option:
B = zeros(max(A));
B(sub2ind(max(A), A(:, 1), A(:, 2))) = 1;
hasconseccols = any(any(conv2(B, [1, 1, 1]) == 3))
hasconsecrows = any(any(conv2(B, [1; 1; 1]) == 3))
which basically fills a matrix with 1 at your given indices, then convolves it with a column or row of three 1. If that result in a 3, you know you have 3 consecutive indices.
5 个评论
Guillaume
2018-9-17
I think I misunderstood a bit what was asked and that the consecutive rows and column must intersect. If that is the case, then the accumarray option would not work.
You can build on my conv2 solution to get the correct result:
B = accumarray(A, 1); %simpler than my initial 2 lines. From matt's answer
[row, centrecol] = find(conv2(B, [1, 1, 1], 'same') == 3); %consecutive columns in a row
[centrerow, col] = find(conv2(B, [1; 1; 1], 'same') == 3); %consecutive rows in a column
colexpanded = (centrecol + [-1, 0, 1])';
rowexpanded = (centrerow + [-1, 0, 1])';
ptsconsecrow = [repelem(row, 3, 1), colexpanded(:)];
ptsconseccol = [rowexpanded(:), repelem(col, 3, 1)];
intersections = intersect(ptsconsecrow, ptsconseccol, 'rows')
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Logical 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!