2017-01-17 7 views
0

ich versuche, eine BGRA Matte mit einem Zeiger wie folgt zu ändern:OpenCV Pixelmanipulation manchmal nicht funktioniert

//Bound the value between 0 to 255 
uchar boundPixelValue(double c) { 
    c = int(c); 
    if (c > 255) 
     c = 255; 
    if (c < 0) 
     c = 0; 
    return (uchar) c; 
} 

for (int i = 0; i < rows; i++) 
     for (int j = 0; j < cols; j++) 
      for (int k = 0; k < 3; k++){ 
       //This loop is accessing the first three channels 
       mat.ptr<Vec4b>(i)[j][k] = boundPixelValue(
         1.0 * mat.ptr<Vec4b>(i)[j][k] * max/avg[k]); 
      } 

Aber das gibt verschiedene Ausgänge jedes Mal, manchmal funktionieren und manchmal eine weiße leere Bild geben. Ich vermute, wenn dies aufgrund der nicht kontinuierlichen Daten ist, kann jemand helfen?

Eine zusätzliche Frage: Normalerweise greifen wir zuerst auf die Spalten eines 2D-Arrays zu, bevor wir auf die Zeilen zugreifen, weil es normalerweise schneller ist. Ich muss jedoch auf das Pixel unter Verwendung mat.ptr<Vec4b>(row)[col] zugreifen. Also, sollte ich zuerst die Zeilen und dann die Spalte durchlaufen?

+0

Was sind 'boundPixelValue',' max', 'avg'? Welche Arten? – Miki

+0

Ich habe den boundPixelValue in der Frage hinzugefügt. "max" ist ein Integer-Typ, "avg" ist ein Integer-Array. – Tim

+0

Überprüfen Sie den Code in meiner Antwort. Ich erkläre besser, was es macht, wenn es für dich funktioniert (ich habe nicht genug Details, um zu garantieren, dass es jetzt funktioniert, siehe bitte [mcve]). – Miki

Antwort

0

einfacher, weniger intensive Art und Weise zu tun, ist:

std::vector<cv::Mat> matArray; 
cv::split(toBoundMat, matArray); 

matArray[0].setTo(0, matArray[0] < 0); 
matArray[0].setTo(255, matArray[0] > 255); 

matArray[1].setTo(0, matArray[1] < 0); 
matArray[1].setTo(255, matArray[1] > 255); 

matArray[2].setTo(0, matArray[2] < 0); 
matArray[2].setTo(255, matArray[2] > 255); 

cv::Mat boundedMat; 

cv::merge(matArray, boundedMat); 

Aber ich verstehe wirklich nicht, was Sie zu tun versuchen. Ihre doppelten Daten können Werte zwischen 1,7E +/- 308 haben. Sie erwarten entweder eine sehr spezifische Art von Daten, oder Sie werden es vermasseln. Wenn Sie eine Matte visualisierbar machen wollen, normalisiert es wie folgen aus:

cv::normalize(inMat, destMat, 0, 255, CV_MINMAX); 

cv::cvtColor(destMat, destMat, CV_8UC1) //--(8 bit visualizable mat) 

Dies wird die min und max Ihrer aktuellen Mat überprüfen und das Minimums auf 0, das Maximum zu 255, und alle in Set zwischen Werten proportional :)

Verwandte Themen