Berechne ein Bildhistogramm mit repa

8

Ich lade ein RGB-Bild von der Festplatte mit JuicyPixels-repa . Leider ist die Array-Darstellung des Bildes Array F DIM3 Word8 , wobei die innere Dimension die RGB-Pixel ist. Das ist ein bisschen inkompatibel mit existierenden repa Bildverarbeitungsalgorithmen, wo ein RGB Bild Array U DIM2 (Word8, Word8, Word8) ist.

Ich möchte die RGB-Histogramme des Bildes berechnen, ich suche eine Funktion mit der Signatur:

%Vor%

Wie kann ich mein 3D-Array falten, um ein 1d-Array für jeden Farbkanal zu erhalten?

Bearbeiten:

Das Hauptproblem ist nicht, dass ich nicht von DIM3 auf DIM2 für jeden Kanal umwandeln kann (einfach gemacht mit Slicing). Das Problem ist, dass ich das Quell-Image DIM2 oder DIM3 iterieren muss und zu einem DIM1 -Array mit einem anderen Shape (Z:.256) und -Erweiterung akkumulieren muss. Daher kann ich nicht die foldS von repa verwenden, da sie die Dimension um eins reduziert, aber im selben Umfang.

Ich habe auch mit traverse experimentiert, aber es iteriert über die Ausdehnung des Zielbildes und bietet eine Funktion, um Pixel aus dem Quellbild zu bekommen, was zu sehr ineffizientem Code führen würde, der die gleichen Pixel für jeden Farbwert zählt. p>

Ein guter Weg wäre eine einfache Faltung über einen Vector mit dem Histogramm-Typ als Akkumulator, aber leider habe ich kein U (unboxed) oder V (Vektor) basiertes Array, von dem ich effizient profitieren kann ein Code%. Ich habe ein Vector (fremder Zeiger).

    
Falco Hirschenberger 08.11.2012, 22:15
quelle

1 Antwort

7

Ok, ich habe ein paar Minuten gefunden. Im Folgenden behandle ich vier Lösungen und habe die schlechtesten Lösungen (die mittleren zwei mit O (n) Datenkonvertierung) wirklich einfach für Sie gemacht.

Lasst uns die dumme Lösung bestätigen

Es ist sinnvoll, mit dem Offensichtlichen zu beginnen. Sie könnten Data.List.foldl verwenden, um die Zeilen und Spalten zu durchlaufen, indem Sie Ihre Histogramme aus den ursprünglichen Nullenarrays aufbauen (ungeprüfter / partieller Code folgt):

%Vor%

Ich bin mir nicht sicher, wie effizient das sein wird, aber ich vermute, dass es zu viele Kontrollen machen wird. Die Umstellung auf unsafeIndex sollte vernünftigerweise funktionieren, wenn man annimmt, dass die verzögerten Arrays hist* gut funktionieren, je nachdem, wie Sie incElem implementieren möchten.

Sie können das Array erstellen, das Sie möchten

Mit traverse können Sie JP-Repa Style-Arrays in DIM2 Arrays mit Tupeln für Elemente konvertieren:

%Vor%

Könnten Sie mich auf den Code hinweisen, über den Sie gesprochen haben und der dieses Format verwendet? Es wäre einfach, JP-Repa mit einer Funktion dieses Typs zu versehen.

Sie können den Unboxed-Vektor erstellen, den Sie erwähnt haben

Sie haben erwähnt, dass eine einfache Lösung darin besteht, ungepackte Vektoren zu falten, beklagte jedoch, dass JP-repa kein ungepacktes Array bietet. Zum Glück ist die Konvertierung einfach:

%Vor%

Wir könnten Repa packen

Das ist wirklich nur ein Problem, weil Repa nicht das hat, was ich als normale traverse -Funktion betrachte. Repas Traverse ist eher eine Array-Konstruktion, die zufällig eine Indizierungsfunktion in einem anderen Array bereitstellt. Wir wollen durchqueren in der Form:

%Vor%

aber grob gesagt ist das eigentlich nur eine missgebildete Falte. So können wir es umbenennen und die Argumente neu anordnen:

%Vor%

, die sich sehr gut von der (bereits vorhandenen) Operation foldAllS unterscheidet:

%Vor%

Beachten Sie, dass unsere neue Falte zwei entscheidende Eigenschaften hat. Der Ergebnistyp muss nicht mit dem Elementtyp übereinstimmen, daher könnten wir mit einem Histogramm-Tupel beginnen. Zweitens übergibt unsere Version von fold den Index, mit dem Sie auswählen können, welches Histogramm im Tupel aktualisiert werden soll (falls vorhanden).

Sie können die neuesten JuicyPixels-Repa getrost verwenden

Um Ihr bevorzugtes Repa-Array-Format zu erhalten oder um einen ungeschachtelten Vektor zu erhalten, können Sie einfach die neu hochgeladenen JuicyPixels-Repa-0.6 verwenden.

%Vor%

Nun können Sie über den Vektor falten oder das Tupel-Array direkt verwenden, wie Sie es ursprünglich gewünscht haben.

Ich habe auch einen hässlichen Stich gemacht, um die erste, entsetzlich naive Lösung auszuarbeiten:

%Vor%

Ich bin zu vorsichtig mit der Leistung dieses Codes (3 Traversale pro Index ... ich muss müde sein), um es in JP-Repa zu werfen, aber wenn Sie finden, dass es gut funktioniert, lassen Sie es mich wissen.

>     
Thomas M. DuBuisson 10.11.2012, 07:40
quelle

Tags und Links