2017-02-08 2 views
3

Ich möchte eine ähnliche Tonkurve realisieren.OpenCV Tone Curve progromatisch

Ich habe vordefinierte Kurven, die ich auf das Bild anwenden sollte. Zum Beispiel: enter image description here

wie ich auf dieses Diagramm wir Abhängigkeiten von aktuellen Tonwert zu neuen sehen verstehen, zum Beispiel: wenn wir ersten Punkt auf der linke Seite zu bekommen - das 0 wird = jeden r, g und b konvertiert in 64 oder jeder Wert von mehr als 224 wird in 0 und ect konvertiert. ich habe vereinfachte Kurve

so habe ich versucht,

für Testzwecke für jedes Pixel des Bildes auf den neuen Wert zu ändern:

enter image description here

und hier den Code, den ich habe:

//init original image 
cv::Mat originalMat = [self cvMatFromUIImage:inputImage]; 

//out image the same size 
cv::Mat outMat  = [self cvMatFromUIImage:inputImage]; 

//loop throw every row of image 
for(int y = 0; y < originalMat.rows; y++){ 
    //loop throw every column of image 
    for(int x = 0; x < originalMat.cols; x++){ 
    //loop throw every color channel of image (R,G,B) 
    for(int c = 0; c < 3; c++){ 

     if(originalMat.at<cv::Vec3b>(y,x)[c] <= 64) 
     outMat.at<cv::Vec3b>(y,x)[c] = 64 + (originalMat.at<cv::Vec3b>(y,x)[c]) - 
     (originalMat.at<cv::Vec3b>(y,x)[c]) * 2 ; 

     if((originalMat.at<cv::Vec3b>(y,x)[c] > 64)&&(originalMat.at<cv::Vec3b>(y,x)[c] <= 128)) 
     outMat.at<cv::Vec3b>(y,x)[c] = ((originalMat.at<cv::Vec3b>(y,x)[c]) - 64 ) * 4 
     ; 

     if((originalMat.at<cv::Vec3b>(y,x)[c] > 128)) 
     outMat.at<cv::Vec3b>(y,x)[c] = (originalMat.at<cv::Vec3b>(y,x)[c]) + 128 - 
     ((originalMat.at<cv::Vec3b>(y,x)[c]) - 128) * 3; 

    } //end of r,g,b loop 
    } //end of column loop 
} //end of row loop 

//send to output 
return [self UIImageFromCVMat:outMat]; 

aber hier das Ergebnis, das ich bekomme: enter image description here

nur 10

aus irgendeinem Grund 3/4 Bild verarbeitet wurde

und es passt nicht mit dem Ergebnis, ich erwartet hatte: enter image description here

aktualisieren 0

dank @ACCurrent Kommentar gefunden Fehler in der Berechnung (Code und Bild aktualisiert), aber immer noch nicht verstehen, warum nur 3/4 der Bilder verarbeitet.

nicht sicher, dass verstehen, warum 'Lärm' erscheint, hoffe es wegen der Kurve nicht glatt.

sieht den Weg aus, .at Betrieb zu vermeiden.

aktualisieren 1

Originalbild:

enter image description here

+1

Vermeiden Sie die Verwendung von opencv '.bei <> 'Funktion ist es sehr langsam. Auch bei der ersten Inspektion nehmen wir den Wert bei 'gaussMat.at an. (y, x) [c]' = 128 Dann: 'if ((gaussMat.at (y, x) [c]> 64) && (gaussMat.at (y, x) [c] <= 128)) outMat.at (y, x) [C] = (gaussMat.at (y, x) [c]) - 64 + (gaussMat.at (y, x) [c]) * 4' Also 128-64 + 128 * 4 ist gleich 576, weit über 255 der Maximalwert für CV_U8c. Es wird also viel Sättigung geben. – ACCurrent

+1

Können Sie das Originalbild auch posten? Und keine Sorge ... die 'at'-Funktion ist nicht langsam. Sie können es ohne Probleme verwenden. – Miki

+0

@Miki Originalbild hinzugefügt – user5599807

Antwort

3

Sie müssen die Bilder zugreifen mit Vec4b


originalMat.typ e() ist gleich zu 24

Ihre originalMat ist vom Typ 24, das heißt CV_8UC4. Dies bedeutet, dass das Bild 4 Kanäle hat, aber Sie greifen mit Vec3b darauf zu, als ob es nur 3 Kanäle hat. Dies erklärt, warum etwa 1/4 des Bildes nicht verändert wird.

Ersetzen Sie also einfach alle Vec3b in Ihrem Code durch Vec4b.