Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blockproc-like function for cell array output

Tags:

matlab

I like blockproc, it makes working with large (very large) images easily. However, as far as I understand, it is limited to working with functions that output a matrix of the same size as the input they take.

So I was wondering if there is a way of replicating/simulating what blockproc does but for functions that output a cell array. We can either assume that the output array from the processing function is of the same dimensions of the input matrix, or that it just outputs one cell element, in which case the final output from the total processing would be a cell array with M x N elements, with M and N specifying the tiling for the processing.

I believe I can build this myself using cellfun, but I was wondering if there is are any other builtins or libraries (maybe third-party?) that I can use for this, and maybe even completely avoid reinventing the wheel.

More specifically, I am looking for something that has the same strengths as blockproc:

  • Can load a large image from disk progressively tile-by-tile to minimize the memory footprint of the processing
  • Takes care of the final concatenation of results for building the final cell array
  • Has an interface similar to blockproc (e.g. # of tiles, etc.)
like image 243
Amelio Vazquez-Reina Avatar asked Nov 05 '22 15:11

Amelio Vazquez-Reina


1 Answers

Below is a solution that satisfies your criteria except for the first point

Use the IM2COL function to arrange distinct image blocks from the image into columns, then apply your function to each column storing the result in a cell array.

Of course this only works if all blocks fit into memory, otherwise you would have to manually write code that extracts one block at a time and process it in that way...

%# read image
img = im2double(imread('tire.tif'));

%# blocks params
sizBlk = [8 8];
numBlk = ceil( size(img) ./ sizBlk );

%# extract blocks
B = im2col(img, sizBlk, 'distinct');
B = reshape(B, [sizBlk size(B,2)]);    %# put blocks on the 3rd dimension
B = squeeze( num2cell(B,[1 2]) );      %# convert to cell array
B = reshape(B, numBlk);                %# reshape as blocks overlayed on image

%# process blocks
myFcn = @(blk) [mean2(blk) std2(blk)]; %# or any other processing function
I = cellfun(myFcn, B, 'UniformOutput',false);

%# in this example, we can show each component separately
subplot(121), imshow( cellfun(@(c)c(1),I) ), title('mean')
subplot(122), imshow( cellfun(@(c)c(2),I) ), title('std')

Alternatively, you could still use the BLOCKPROC function, but you have to call it multiple times, each time computing a single feature:

%# compute one feature at a time
b1 = blockproc(img, sizBlk, @(b)mean2(b.data), 'PadPartialBlocks',true);
b2 = blockproc(img, sizBlk, @(b)std2(b.data), 'PadPartialBlocks',true);

%# combine into cellarray of features
II = arrayfun(@(varargin)[varargin{:}], b1, b2, 'UniformOutput',false);

%# compare to previous results
isequal(I,II)
like image 96
Amro Avatar answered Nov 09 '22 04:11

Amro