GIMP und OpenCV
Histogramme mit OpenCV auswerten

GIMP und OpenCV

Eigentlich haben GIMP und OpenCV nicht so viel gemeinsam. Denn GIMP dient der Bildbearbeitung, während OpenCV ein mächtiges Werkzeug zur Bildverarbeitung ist. Aber wer sich gut mit GIMP (oder auch Photoshop) auskennt, wird es einfacher haben einige Konzepte von OpenCV zu verstehen. Die nachfolgenden Screenshots sind mit GIMP 2.10.8 auf einem Raspberry Pi 4 entstanden. Beginnen wir mit zwei beliebten Operationen: Kontrastspreizung und Gammakorrektur. Beide Operationen verändern das Histogramm:

GIMP Kurvenwerkzeug
Ein dunkles Bild und dessen Histogramm

In der Abbildung sehen Sie links das recht dunkle Originalbild (ein digitalisiertes Dia) und rechts einen GIMP-Dialog. Mit dem  Werkzeug „Kurven“ können die Helligkeitswerte im Histogramm neu verteilt werden (Farben/Kurven im Menü). Wenn Sie dabei eine Gerade sehen, haben Sie in der Vorschau noch den Originalzustand. Wenn Sie die Gerade am oberen rechten Punkt anfassen und nach links verschieben, bekommen Sie eine lineare Kontrastspreizung. Eine Durchbiegung der Kurve nach oben führt ebenso zu einem helleren und kontrastverstärkten Bild:

Umverteilung der Histogrammwerte
Eine Gammakorrektur hellt dunkle Bereiche auf

Da Sie hier die Kurvenform manuell festlegen, handelt es sich streng genommen nicht um eine Gammakorrektur. Aber auf alle Fälle gibt es (zumindest intern in GIMP) eine Transformationstabelle die pro Farbkanal 256 neue Werte genau eines Farbkanals definiert. Wenn Sie im GIMP-Dialog Farbkurven korrigieren „Kanal Wert“ sehen, dann werden dabei alle drei Farbkanäle R,G,B zugleich verändert. Sie können dort z.B. auch den Kanal „grün“ auswählen und somit nur eine Farbkomponente verändern. Im Menü unter „Farben/Automatisch“ bietet GIMP „Kontrastspreizung“ sowie „Kontrastspreizung (HSV)“ an.

Kontrastspreizung mit GIMP
Operationen im GIMP Menü

In beiden Fällen wird das Histogramm gestreckt (GIMP normiert allgemeingültig auf 0.0 bis 1.0 als Wertebereich) und man erhellt so oft ein schöneres Bild. Bei einem 24 Bit Farbbild hat jeder Farbkanal 8 Bit, was 256 Stufen der Transformationstabelle entspricht. Im C++ Interface von OpenCV kann die Transformationstabelle für einen 8-Bit Kanal so programmiert werden:

unsigned char lut[256];
for (int i = 0; i < 256; i++) // Build look up table
{
lut[i] = saturate_cast(pow((float)(i / 255.0), gamma) * 255.0f);
}

Da hier pow(i/255) mit gamma als Exponent verwendet wird, ist es eine Gammakorrektur. Und exemplarisch kann das Resultat für einen Kanal (exemplarisch aus RGB) so aussehen:

lut[ 11]= 13  delta= 2
lut[ 30]= 39 delta= 9
lut[115]=140 delta=25
lut[128]=153 delta=25
lut[180]=197 delta=17
lut[253]=254 delta= 1

Dabei entspricht i der horizontalen Achse im Histogramm und lut[i] der vertikalen Achse. Nach Anwendung dieser Tabelle auf mindestens einen Farbkanal kommt es zu einer Umverteilung im Histogramm, wobei es immer einen Punkt der maximalen Kurvendurchbiegung (maximales delta) gibt. Bei einer reinen Aufhellung ist delta positiv und konstant (Die Gerade wäre nach oben verschoben). Ein zu hoher Wert für delta bzw. lut[i] kann zu unschönen Überstrahlungen im Bild führen. Die Anwendung der LookUp Tabelle lut[i] sieht so aus:

MatIterator_ it, end;
for (it = out.begin(), end = out.end(); it != end; it++)
{
(*it)[0] = lut[((*it)[0])]; // blue
(*it)[1] = lut[((*it)[1])]; // green
(*it)[2] = lut[((*it)[2])]; // red
}

Alle drei Komponenten der OpenCV Matrix out bekommen so neue Werte.
Bei einer reinen Kontrastverstärkung ist lut[i] linear und damit eine reine Multiplikation (die Steigung der Gerade wird angehoben). Eine rein lineare Kontrastspreizung kann man in OpenCV allerdings auch einfacher bekommen :

Mat imgNorm; // für das kontrastverstärkte Bild
normalize(img3x8.clone(),imgNorm,0.0,255, NORM_MINMAX);
destname = outpath24s + nrbase + "_NormMinMax.jpg";
imwrite(destname, imgNorm);

Dabei ist img3x8 das farbige JPEG-Eingangsbild und imgNorm wird als kontrastgespreiztes neues Bild gespeichert. Bei der grünen Schlange handelt es sich übrigens um ein unterbelichtetes Dia, das per Kamerascanner digitalisiert wurde. In GIMP sieht die lineare Kontrastspreizung so aus:

Dehnung des Histogramms
Lineare Kontrastspreizung mit GIMP

Nach der Kontrastspreizung liegt der hellste Histogrammpunkt nicht mehr unter 128 sondern über 250. Im Histogramm sind durch die Kontrastspreizung Lücken entstanden. Das Bild ist jetzt signifikant heller – und auch heller als das Dia wirkt. Aber Dias werden meist im abgedunkelten Raum vorgeführt, was eine Dunkeladaption der Augen und damit eine bessere Wahrnehmung dunkler Bildpartien bewirkt. In Helligkeit und Kontrast ausgeglichen wirkt solch ein Bild erst nach einer zusätzlichen Gammakorrektur:

Bildaufhellung durch Gammakorrektur
Gammakorrektur bei schon gespreiztem Histogramm

Beachten Sie bitte auch, daß sich seltener vorkommende Werte nur in einem logarithmischen Histogramm erkennen lassen. Beachtet man das nicht, besteht die Gefahr bestimmte Bildteile auf die Extremwerte 0 oder 255 zu setzen. Manchmal ist dieser Effekt aber gewollt, denn übersteigerte Kontraste und satte Farben können zu einem spannenden Bild führen:

Kontrastanhebung
Kontrastanhebung über eine S-förmige Kurve

Solch ein Effekt wird erreicht, indem man durch eine S-förmige Histogrammkurve dunkle und helle Farbtöne fast in die Sättigung abgleiten lässt. Sie sehen an diesem Beispiel, daß es optimale Bilder im Rahmen einer Bildbearbeitung eigentlich nicht gibt. Wie beim Farbempfinden können die Ansichten über „Schönheit“ je nach Betrachter recht unterschiedlich ausfallen. Und nicht jedes Motiv wirkt bei überhöhten Kontrasten gut. Was man bei der Filmemulsion die Gradationskurve nennt, wird heute in der Digitalkamera durch das Belichtungsprogramm vorgegeben.

Bei manchen Bildern ist eine Gammakorrektur der einzige Weg, um aus zu dunklen Bildteilen noch etwas Information herauszuholen:

Aufhellung durch Gammakorrektur
Die Gammakorrektur macht Unsichtbares sichtbar

Das Originalbild ist hier in der rechten oberen Ecke eingeblendet und es ist dort nur ein kleiner Teil des Brückenstegs erkennbar. Das gilt bei diesem Bild auch dann, wenn Sie eine lineare Kontrastspreizung in GIMP oder OpenCV ausprobieren. Der einzige Weg um die dunkleren Bildteile stärker hervortreten zu lassen (ohne Überstrahlungen zu riskieren) ist eine Gammakorrektur. In OpenCV kann man diesen Vorgang auch automatisch für beliebige Bilderstapel durchführen – Ein Vorgang der in GIMP nur manuell durchführbar und auch mit Script-Fu nicht so einfach automatisierbar ist.
Basis ist auf jeden Fall eine gut programmierte Histogrammauswertung für alle Farbkanäle. Eine Speicherung aller Transformationstabellen lut[i] ermöglicht die spätere Anwendung auf Bilder in höherer Auflösung.

Die mühsame manuelle Einstellung in GIMP hat aber noch einen Nachteil: Man sieht immer nur ein Bild und kann nicht die Wirkung unterschiedlicher Bildvarianten in Bezug auf Farbe, Kontrast und Helligkeit  miteinander vergleichen. Die Umsetzung erfolgt dreistufig:

  1. Ein Generatorprogramm verarbeitet den Bilderstapel und erzeugt mehrere Bildvarianten pro Bild
  2. Ein Viewer zeigt die beiden Bildvarianten und zusätzlich ein neues, speicherbares Mischbild an 
  3. Die individuell pro Bild gespeicherten Transformationstabellen und Parameter werden automatisch auf den gesamten Bilderstapel bei voller Auflösung angewandt. (Batchverarbeitung, ohne manuellen Eingriff)

In OpenCV sieht solch ein Mixer (also Stufe2) für Bilder so aus:

Gewichtete Mischung von Bildern
OpenCV-Mixer mit Farb-Histogrammen

Die oberen beiden Bilder ergeben sich aus der unterschiedlichen Verarbeitung bezüglich Gammakorrektur und Weissabgleich. Das mittige untere Mischbild wird nach dem Prozentsatz des Trackbars zusammengesetzt. Beim hier abgebildeten Lama hat die Gammakorrektur (Bild links oben) die gewünschte Aufhellung des Halses bewirkt. Allerdings wird dabei auch das Kamerarauschen auf dem dunklen Hintergrund verstärkt. Das Bild rechts oben ist ein JPEG ohne Gammakorrektur. Der beste Kompromiss ist hier das Mischbild. Die beiden Histogramme zeigen die jeweilige Verteilung der Grauwerte und Farben mit 50% logarithmischer Darstellung. Im linken Histogramm ist das farbige Sensorrauschen für den dunklen Bildhintergrund gut erkennbar. Für die Steuerung gibt es einen eigenen Dialog mit dem alle Bilder verarbeitet werden können. Der OpenCV-Mixer kann mit herunterskalierten Bildern arbeiten, da alle abgespeicherten Transformationstabellen sowie das Mischungsverhältnis in Stufe 3 verwendet werden.  So entsteht ein kompletter Workflow für Digitalbilder / gescannte Dias oder Negative.

Schreibe einen Kommentar