Histogramm-Ausgleich-Methode ohne Verwendung von histeq
Ich bin neu in Matlab und versuche einen code implementieren, um die gleiche Funktion wie histeq
ohne tatsächliche Nutzung Funktion. In meinem code das Bild in Farbe bekomme ich ändert sich drastisch, wenn es sich nicht ändern sollte, der viel. Die durchschnittlichen Intensität in dem Bild (im Bereich zwischen 0 und 255) ist 105.3196. Das Bild ist von einer open-source-pollen Teilchen.
Jede Hilfe wäre sehr geschätzt werden. Je früher, desto besser! Könnte bitte jede Hilfe vereinfacht werden, da mein Matlab Verständnis ist begrenzt. Danke.
clc;
clear all;
close all;
pollenJpg = imread ('pollen.jpg', 'jpg');
greyscalePollen = rgb2gray (pollenJpg);
histEqPollen = histeq(greyscalePollen);
averagePollen = mean2 (greyscalePollen)
sizeGreyScalePollen = size(greyscalePollen);
rowsGreyScalePollen = sizeGreyScalePollen(1,1);
columnsGreyScalePollen = sizeGreyScalePollen(1,2);
for i = (1:rowsGreyScalePollen)
for j = (1:columnsGreyScalePollen)
if (greyscalePollen(i,j) > averagePollen)
greyscalePollen(i,j) = greyscalePollen(i,j) + (0.1 * averagePollen);
if (greyscalePollen(i,j) > 255)
greyscalePollen(i,j) = 255;
end
elseif (greyscalePollen(i,j) < averagePollen)
greyscalePollen(i,j) = greyscalePollen(i,j) - (0.1 * averagePollen);
if (greyscalePollen(i,j) > 0)
greyscalePollen(i,j) = 0;
end
end
end
end
figure;
imshow (pollenJpg);
title ('Original Image');
figure;
imshow (greyscalePollen);
title ('Attempted Histogram Equalization of Image');
figure;
imshow (histEqPollen);
title ('True Histogram Equalization of Image');
- Ein bug (sollte aber nicht der Haupt-Fehler): diese Zeile
if (greyscalePollen(i,j) > 0)
sollteif (greyscalePollen(i,j) < 0)
denke ich. - Ich fühle mich wie ein idiot, haha. Danke. Auch in meiner Linie: greyscalePollen(i,j) = greyscalePollen(i,j) + (0.1 * averagePollen); und greyscalePollen(i,j) = greyscalePollen(i,j) - (0.1 * averagePollen); Die plus-und minus-sollte getauscht werden, haha. So dumm.... Danke 😀
- Ich denke, dass Ihr Algorithmus ist grundlegend falsch. Es erhöht den Kontrast, aber es ist nicht äquivalent zu der Histogramm-Ausgleich.
- Ich bin nicht überrascht... Wie gesagt ich bin ganz neu hier, haha. Hast du irgendwelche Empfehlungen?
- Was Sie tun müssen: berechnen Sie die Anzahl der Pixel in jedem Grauwert Palette (eine bin). Dies gibt eine Funktion
h(g)
. Nun aus, die kumulative Summe, dassH(g)=h(g)+h(g_previous)+h(g_previous_previous)...
etc. Dann berechnen Sie die inverse dieser Funktion, H^-1, und wenden Sie dann diese Funktion, um das Bild. Mathe hier: en.wikipedia.org/wiki/Histogram_equalization; Umsetzung hier "code" -spot.co.za/2008/09/21/... - Ich verwendet imhist vergleichen Sie die Histogramme erzeugt durch meine Methode und die eigentliche Entzerrung und, wie Sie sagte, sind Sie sehr unterschiedlich...
- Ich werde zu erweitern mein Kommentar in eine Antwort.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Zur Umsetzung der entzerrungs-Algorithmus beschrieben, auf der Wikipedia-Seite, befolgen Sie diese Schritte:
Entscheiden Sie sich für eine
binSize
Gruppe von Graustufen. (Dies ist eine tweakable, die größer die bin, die weniger genau ist das Ergebnis vom Idealfall aus, aber ich denke, es kann Probleme verursachen, wenn zu klein gewählt, die auf echten Bildern).Dann berechnen Sie die Wahrscheinlichkeit, dass ein pixel eine Schattierung von Grau:
Das Histogramm in diese Berechnung skaliert wird (dividiert durch die pixel-Anzahl), so dass die Werte sinnvoll als Wahrscheinlichkeiten. Sie können natürlich ein Faktor der division aus der for-Schleife.
Nun müssen Sie berechnen Sie die kumulierte Summe dieser:
Nun müssen Sie umkehren diese Funktion und das ist der schwierige Teil. Das beste ist, um nicht berechnen Sie eine explizite inverse, aber berechnen es auf der Stelle, und wenden Sie es auf das Bild. Die Grundidee ist, die Suche nach den pixel-Wert in der histogramSum (finden Sie den nächsten index unten), und dann eine lineare interpolation zwischen dem index und dem nächsten index.
Edit: ohne bohren in Mathe, ich kann nicht 100% sicher, aber ich glaube, dass die division durch 0 Fehler sind möglich. Diese können auftreten, wenn ein Fach leer ist, also aufeinander folgenden Summen sind gleich. So benötigen Sie spezielle code in diesem Fall behandeln zu. Die besten können Sie tun ist, nehmen Sie den Wert für den Faktor auf halbem Weg zwischen
hIndex
,hIndex + n
, won
ist der höchste Wert, für diehistogramSum[hIndex + n] == histogramSum[hIndex]
.Ist und dass sollte werden es, sobald Sie sich mit allen Formalitäten.
Den oben beschriebenen Algorithmus ist langsam (vor allem in der findIndex Schritt). Sie können in der Lage sein, um dies zu optimieren, mit einem speziellen lookup-datastructure. Aber nur, wenn es funktioniert, und nur wenn notwendig.
Eine weitere Sache über Ihren Matlab-code: die Zeilen und Spalten sind vertauscht. Aufgrund der Symmetrie des Algorithmus das Ergebnis ist das gleiche, aber es kann die Ursache für rätselhafte Fehler in anderen algorithmen, und sehr verwirrend sein, wenn Sie prüfen, pixel-Werte während des Debuggens. In der pseudocode oben habe ich das gleiche wie du, obwohl.
Relativ wenige (5) code-Zeilen kann dies tun. Ich verwendet ein low-contrast-Datei mit dem Namen 'pollen.jpg' das fand ich bei http://commons.wikimedia.org/wiki/File%3ALepismium_lorentzianum_pollen.jpg
Ich lese es in Ihren code verwenden, führen Sie alle oben genannten, dann tun Sie das folgende:
Wenn ich dieses Algorithmus, und erstellen Sie dann einen Verbund aus den vier Bildern (original, deinen Versuch, mein Versuch, und
histeq
), erhalten Sie die folgenden:Ich denke, es ist überzeugend. Die Bilder sind nicht genau identisch - ich glaube, das ist, weil die matlab
histeq
routine ignoriert alle Pixel mit dem Wert 0. Da ist es voll vektorisiert es ist auch ziemlich schnell (wenn auch nicht annähernd so schnell, wiehisteq
etwa um den Faktor 15 auf mein Bild.EDIT: ein bisschen Erklärung könnte in Ordnung sein. Die
repmat
Befehl, den ich verwenden, um dienewVals
matrix erzeugt eine matrix, die wie folgt aussieht:Da matlab speichert Matrizen in "first index first" um, wenn Sie Lesen, diese matrix mit einem einzigen index (wie ich tun in der Zeile
newVals(1:N)
), gelangen Sie zuerst alle Nullen, dann alle Einsen, usw:So - wenn ich weiß, dass die Indizes der Pixel in der Reihenfolge Ihrer Intensität (zurückgegeben durch das zweite argument der
sort
Befehl, den ich genanntgi
), dann kann ich einfach den Wert zuzuweisen0
zu den erstenN/256
Pixel, der Wert1
zum nächstenN/256
etc, mit dem Befehl, den ich verwendet:Ich hoffe, das macht den code ein wenig einfacher zu verstehen.