Blockproc-подобная функция для вывода массива ячеек - PullRequest
5 голосов
/ 02 сентября 2011

Мне нравится blockproc, это облегчает работу с большими (очень большими) изображениями. Однако, насколько я понимаю, он ограничен работой с функциями, выводящими матрицу того же размера, что и входные данные, которые они принимают.

Поэтому мне было интересно, есть ли способ репликации / симуляции того, что делает blockproc, но для функций, которые выводят массив ячеек . Мы можем либо предположить, что выходной массив из функции обработки имеет те же размеры входной матрицы, либо он просто выводит один элемент ячейки, и в этом случае окончательный результат всей обработки будет массивом ячеек с M x N элементы, с M и N, указывающими тайлинг для обработки.

Полагаю, я могу построить это сам, используя cellfun, но мне было интересно, есть ли какие-нибудь другие встроенные функции или библиотеки (возможно, сторонние?), Которые я могу использовать для этого, и, возможно, даже полностью избегайте изобретать велосипед.

В частности, я ищу что-то такое же сильное, что и blockproc:

  • Может загружать большое изображение с диска постепенно по частям, чтобы минимизировать использование памяти при обработке
  • Заботится об окончательном объединении результатов для построения окончательного массива ячеек
  • Имеет интерфейс, подобный blockproc (например, количество плиток и т. Д.)

Ответы [ 2 ]

2 голосов
/ 03 сентября 2011

Ниже приведено решение, которое удовлетворяет вашим критериям, за исключением первого пункта

Используйте функцию IM2COL, чтобы упорядочить отдельные блоки изображения из изображения в столбцы, затем примените свою функцию к каждому столбцу, хранящему результат в массиве ячеек.

Конечно, это работает, только если все блоки помещаются в память, в противном случае вам придется вручную писать код, который извлекает один блок за раз, и обрабатывать его таким образом ...

%# 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')

В качестве альтернативы, вы все равно можете использовать функцию BLOCKPROC, но вам придется вызывать ее несколько раз, каждый раз вычисляя одну функцию:

%# 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)
0 голосов
/ 05 июня 2013

Я делал нечто подобное, хотя с числовыми значениями, а не с ячейками.

Что-то вроде этого должно работать:

I = imread('pout.tif'); 

G = blockproc(I, [8 8], @(b) shiftdim(imhist(b.data)', -1), 'PadPartialBlocks', true);

G = reshape(G, size(G, 1) * size(G, 2), size(G, 3));

pout.tif - это изображение в градациях серого, но яЯ уверен, что это может быть изменено для RGB.

Также будьте осторожны при использовании shiftdim, imhist возвращает вектор строки, чтобы я перенес его в столбец.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...