问题
I have a 50x50 matrix, and I'd like to sum up the values in every 10x10 (or another set size value - always square) overlapping grid i.e.:
Overlapping windows are shown only in the diagonal for the sake of clarity. The first task I've tried to do is define the coordinates of each window:
win=10;
start = [1,10,1,10];
for y=1:(50-win)
for g=1:(50-win)
tmp = [start(g,1)+1,start(g,2)+1,start(end,3),start(end,4)];
start = [start;tmp];
end
start(end+1,1:4) = [1,10,1+y,10+y];
end
And then I'd loop over the list of coordinates, using sum
and logical indexing for each window.
PROBLEM #1: The above code is not particularly eloquent. Can anybody show a more 'MATLABesque' way of doing it or a more concise way?
PROBLEM #2: I'd then like to define a particular coordinate (index) in the matrix e.g. m(26,26)
and get a list of all windows this coordinate is contained within. But I have no idea how to do this. Can anybody show me how?
回答1:
Problem #1
The most Matlab-like way for doing this I can think of is two-dimensional convolution (conv2) (as I now see was commented by @rahnema1):
M = randi(9, 5, 5); % input: square matrix, arbitrary size
N = 3; % block size, assumed square, not larger than M
result = conv2(M, ones(N), 'valid');
Equivalently, you can use the recently introduced movsum function, twice (once for each dimension):
result = movsum(movsum(M, N, 1, 'Endpoints', 'discard'), N, 2, 'Endpoints', 'discard');
Example:
M =
4 4 3 1 2
2 8 7 1 6
3 6 7 5 5
6 5 4 8 1
5 9 6 9 4
result =
44 42 37
48 51 44
51 59 49
Problem #2
The simplest way (not the most efficient one) is to use convolution again with a logical matrix containing true
at the desired position and false
otherwise, and checking where the convolution is not zero:
in_coords = [3 4]; % example input coordinates
T = false(size(M)); % initiallize matrix containing false, same size as M
T(in_coords(1), in_coords(2)) = true; % true at the desired coordinates
C = conv2(T, ones(N), 'valid'); % this gives 1 for blocks affected by in_coords
[ii, jj] = find(C); % row and column indices of nonzero values
out_coords = [ii jj]; % build result
In this example,
out_coords =
1 2
2 2
3 2
1 3
2 3
3 3
回答2:
EDIT: you want the conv2
solution. I answered this when you only asked whats in in the body, and not comments, so I answered on how to get the diagonal sliding of the windows. If you want all, you want conv2
as Luis suggests.
Answer to #1
num_pixels_box=10;
offset=[1,1];
num_offsets=size(img,1)/num_pixels_box; % assumes square image and box
for ii=1:num_offsets
index_start=[0,0]+ii*offset;
index_end = index_start+[num_pixels_box-1,num_pixels_box-1];
result(ii)=sum(sum(img(index_start(1):index_end(1),index_start(2):index_end(2))));
end
I havent tested it, but should be the general idea on how to crate it in a MATLABesque way. you can combine these things into other variables, or more compact forms, but I hope this way it makes sense.
Answer to #2
If you have upper and lower bounds of a square, knowing if a point is inside of it its just couple of if conditions. Make a function is_in_square()
for clarity. Then just loop over existing windows.
来源:https://stackoverflow.com/questions/63055349/sliding-window-summation-of-a-matrix