سؤال

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)));
هل كانت مفيدة؟

المحلول

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)));
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top