2011-09-02 10 views
5

Mi piace blockproc, rende facile il lavoro con immagini grandi (molto grandi). Tuttavia, per quanto ho capito, è limitato a lavorare con le funzioni che emettono una matrice della stessa dimensione dell'ingresso che prendono.Funzione blockproc per uscita array di celle

quindi mi chiedevo se c'è un modo di replicare/simulando quello blockproc fa, ma per le funzioni che uscita di un array di celle. Possiamo supporre che l'array di output della funzione di elaborazione abbia le stesse dimensioni della matrice di input o che emetta solo un elemento di cella, nel qual caso l'output finale dall'elaborazione totale sarebbe un array di celle con elementi M x N, con M e N specificando la piastrellatura per l'elaborazione.

Credo di poterlo costruire io stesso usando cellfun, ma mi chiedevo se ci sono altri builtin o librerie (forse di terze parti?

In particolare, sto cercando qualcosa che ha gli stessi punti di forza come blockproc:

  • può caricare una grande immagine da disco progressivamente tile-by-tile per ridurre al minimo l'occupazione di memoria del trattamento
  • Si prende cura della concatenazione finale dei risultati per la costruzione della matrice cellulare finale
  • ha un'interfaccia simile a blockproc (ad esempio # di piastrelle, ecc)
+0

Suppongo che il tuo array di celle contenga dati "complicati" in modo che non puoi semplicemente avvolgere la tua funzione in ['cell2mat'] (http://www.mathworks.de/help/techdoc/ref/cell2mat.html) e usare 'blockproc'? –

+0

Proprio così @ Jonas.Sto cercando una soluzione che non faccia alcuna ipotesi sulla cella di output dalla funzione che esegue l'elaborazione (ad esempio, il suo contenuto, ecc.) –

risposta

2

Di seguito è una soluzione che soddisfa i criteri tranne il primo punto

Utilizzare la funzione IM2COL per disporre blocchi di immagine distinti dall'immagine in colonne, quindi applicare la funzione a ogni colonna che memorizza il risultato in una matrice di celle.

Naturalmente questo funziona solo se tutti i blocchi si adattano in memoria, altrimenti si sarebbe dovuto scrivere manualmente il codice che estrae un blocco alla volta ed elaborare in quel modo ...

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

In alternativa, si potrebbe ancora utilizzare la funzione BLOCKPROC, ma devi chiamare più volte, ogni volta calcolo di una sola caratteristica:

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

Grazie! Questo è così utile. –

0

che ho fatto qualcosa di simile, anche se con nume valori ric, piuttosto che celle.

Qualcosa del genere dovrebbe funzionare:

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 è un'immagine in scala di grigi, ma sono sicuro che questo può essere modificato per RGB.

Inoltre, fare attenzione quando si utilizza shiftdim, imhist restituisce un vettore di riga in modo che lo trasponga in una colonna.

Problemi correlati