问题
I've an image of size [M,N]
, which I would like to split into overlapping
blocks of size [rr,cc]
. Each block is shifted by yy
and xx
pixels. The code below does the job. Is there any more efficient way to do that? e.g. avoiding the for
loops? The solutions that I found approach #1 or approach #2 where mainly for non-overlapping
blocks.
SOL 1
Im = imread('cameraman.tif');
[M,N,~] = size(Im);
rr = 64; cc = 64; xx = 32; yy = 32;
numBlocksYY = numel(1:rr-xx:(M-(rr-1)));
numBlocksXX = numel(1:cc-yy:(N-(cc-1)));
[numBlocksYY, numBlocksXX]
C = cell(numBlocksYY*numBlocksXX,1);
counter = 1;
for ii=1:rr-xx:(M-(rr-1))
for jj=1:cc-yy:(N-(cc-1))
fprintf('[%d:%d, %d:%d]\n',ii,ii+rr-1,jj,jj+cc-1);
C{counter} = Im(ii:(ii+rr-1), jj:(jj+cc-1), : );
counter = counter + 1;
end
fprintf('\n');
end
figure;
for ii=1:numBlocksYY*numBlocksXX
subplot(numBlocksYY,numBlocksYY,ii), imagesc( C{ii} ); axis image; colormap gray;
end
SOL 2
Inspired by some of the solutions proposed in this post, I tried to come to a solution using ndgrid
, but how could I later on fill the output cell C
and access to the sub-images using the XX
and YY
indexes? I'm also curious to see if there are any other solutions :-) ?
[YY,XX]=ndgrid( 1:(rr-xx):(M-(rr-1)) , 1:(cc-yy):(N-(cc-1)));
回答1:
You can obtain the output cell C
from XX
and YY
given in SOL 2 as follows:
% indices of the first rr x cc block
IDX1 = bsxfun(@plus, (1:rr)', ((1:cc)-1)*M);
% offset in indices for each block
offset = (XX(:)-1) + (YY(:)-1)*M;
% indices of each block, the block is indexed with the 3rd dimension
IDX = bsxfun(@plus, IDX1, reshape(offset, [1 1 numel(offset)]));
% convert to cell of blocks
C = mat2cell(Im(IDX), rr, cc, ones(1, numel(XX)));
来源:https://stackoverflow.com/questions/22271101/matlab-splitting-images-into-overlapping-blocks