5 Stimmen

Blockproc-ähnliche Funktion für die Ausgabe von Zellenfeldern

Ich mag blockproc Es erleichtert die Arbeit mit großen (sehr großen) Bildern. Allerdings, soweit ich verstehe, ist es auf die Arbeit mit Funktionen beschränkt, die eine Matrix ausgeben mit der gleichen Größe wie die Eingabe, die sie annehmen.

Ich frage mich also, ob es eine Möglichkeit gibt, das zu replizieren/simulieren, was blockproc tut, sondern für Funktionen, die ein Zellen-Array ausgeben . Wir können entweder davon ausgehen, dass das Ausgabe-Array der Verarbeitungsfunktion die gleichen Dimensionen wie die Eingabematrix hat, oder dass sie nur ein Zellenelement ausgibt; in diesem Fall wäre die endgültige Ausgabe der gesamten Verarbeitung ein Zellen-Array mit M x N Elemente, mit M y N Angabe der Kacheln für die Verarbeitung.

Ich glaube, ich kann das selbst bauen, indem ich cellfun aber ich habe mich gefragt, ob es irgendwelche anderen Builtins oder Bibliotheken (vielleicht von Drittanbietern?) gibt, die ich dafür verwenden kann, und vielleicht sogar ganz vermeiden, das Rad neu zu erfinden.

Genauer gesagt, suche ich etwas, das die gleichen Stärken hat wie blockproc :

  • Kann ein großes Bild schrittweise von der Festplatte laden, um den Speicherbedarf für die Verarbeitung zu minimieren
  • Übernimmt die abschließende Verkettung der Ergebnisse zur Erstellung des endgültigen Zellenfelds
  • Hat eine ähnliche Schnittstelle wie blockproc (z.B. Anzahl der Kacheln, etc.)

2voto

Amro Punkte 122495

Im Folgenden finden Sie eine Lösung, die Ihre Kriterien mit Ausnahme des ersten Punktes erfüllt

Verwenden Sie die Funktion IM2COL, um die einzelnen Bildblöcke des Bildes in Spalten anzuordnen, und wenden Sie dann Ihre Funktion auf jede Spalte an, indem Sie das Ergebnis in einem Zellenfeld speichern.

Das funktioniert natürlich nur, wenn alle Blöcke in den Speicher passen, andernfalls müsste man manuell Code schreiben, der einen Block nach dem anderen extrahiert und auf diese Weise verarbeitet...

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

Alternativ können Sie auch die Funktion BLOCKPROC verwenden, aber Sie müssen sie mehrfach aufrufen, wobei jedes Mal ein einzelnes Merkmal berechnet wird:

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

0voto

Nicholas McCarthy Punkte 324

Ich habe etwas Ähnliches gemacht, allerdings mit numerischen Werten und nicht mit Zellen.

So etwas sollte funktionieren:

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 ist ein Graustufenbild, aber ich bin mir sicher, dass man es auf RGB umstellen kann.

Achten Sie auch darauf, wenn Sie shiftdim verwenden, imhist gibt einen Zeilenvektor zurück, also transponiere ich ihn in eine Spalte.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X