2016-05-23 8 views
3

Ich habe ein Graustufenbild, das nur schwarz und weiß enthält. Es gibt einige isolierte schwarze Pixel aufgrund von Rauschen, die ich gerne loswerden möchte. Ich weiß, dass das Öffnen und Schließen eine Lösung sein könnte, aber ich habe das Gefühl, dass sie für mein Image nicht optimal sind. Also schrieb ich folgendes:OpenCV/C++ - Bearbeiten Sie alle isolierten Pixel

for (int i = 1; i < pixels.rows; ++i) { 
    for (int j = 1; j < pixels.cols; ++j) { 
     if ((pixels.at<char>(i, j) == 0) && 
      (pixels.at<char>(i - 1, j) == 255) && 
      (pixels.at<char>(i, j - 1) == 255) && 
      (pixels.at<char>(i + 1, j) == 255) && 
      (pixels.at<char>(i, j + 1) == 255)) { 
      pixels.at<char>(i, j) = 255; 
     } 
    } 
} 

Es soll durch mein Bild laufen und prüfen, ob das Pixel schwarz ist und seine Nachbarschaft weiß ist. Wenn dies der Fall ist, sollte das Pixel auch in ein weißes Pixel umgewandelt werden. Ich lief dies auf einem Testbild, das von diesem Mat erstellt wurde:

Mat pixels = (Mat_<float>(5, 5) << 
    255, 255, 255, 255, 255, 
    255, 0, 255, 0, 255, 
    255, 255, 255, 255, 255, 
    255, 0, 255, 0, 255, 
    255, 255, 255, 255, 255); 

Wenn ich den Code nichts lief passiert ist, nur das Originalbild erschien ...

Wenn ich eine einfachere Version von lief der Code, es hat funktioniert, also sollte die Syntax eigentlich stimmen:

for (int i = 1; i < pixels.rows; ++i) { 
    for (int j = 1; j < pixels.cols; ++j) { 
     if ((pixels.at<char>(i, j) == 0)) { 
      pixels.at<char>(i, j) = 255; 
     } 
    } 
} 

Findet jemand meinen Fehler darin?

+2

Haben Sie versucht, durch den Code schrittweise die bedingte Anweisung sehen versagt, und was sind die Werte? – Hill

Antwort

3

Die Prozedur ist grundsätzlich korrekt, aber Sie erstellen eine Matfloat und Sie greifen darauf als char. Sie müssen den Typ identisch sein.

Auch Ihre Iterationsbereiche müssen korrigiert werden. Sie können auch überprüfen, 8-Verbindung, sonst wird Ihr Bild mit dem zentralen Pixel auf 0 nicht wie erwartet

Denken Sie daran, dass char Bereich ist [-128, +127], so wird es nie gleich vergleichen zu 255.

Hier ist ein Arbeitsbeispiel. Ich benutzte uchar da es die Art ist, müssen Sie wahrscheinlich, da Sie auf ein Graustufenbild arbeiten:

#include <opencv2/opencv.hpp> 
#include <iostream> 
using namespace cv; 

int main() 
{ 
    Mat pixels = (Mat_<uchar>(5, 5) << 
     255, 255, 255, 255, 255, 
     255, 0, 255, 0, 255, 
     255, 255, 255, 255, 255, 
     255, 0, 255, 0, 255, 
     255, 255, 255, 255, 255); 

    for (int i = 1; i < pixels.rows - 1; ++i) { 
     for (int j = 1; j < pixels.cols - 1; ++j) 
     { 
      if ((pixels.at<uchar>(i, j) == 0) && 
       (pixels.at<uchar>(i - 1, j - 1) == 255) &&  // Top Left 
       (pixels.at<uchar>(i - 1, j + 0) == 255) &&  // Top 
       (pixels.at<uchar>(i - 1, j + 1) == 255) &&  // Top Right 
       (pixels.at<uchar>(i + 0, j - 1) == 255) &&  // Left 
       (pixels.at<uchar>(i + 0, j + 1) == 255) &&  // Right 
       (pixels.at<uchar>(i + 1, j - 1) == 255) &&  // Bottom Left 
       (pixels.at<uchar>(i + 1, j + 0) == 255) &&  // Bottom 
       (pixels.at<uchar>(i + 1, j + 1) == 255)   // Bottom Right 
       ) 
      { 
       pixels.at<uchar>(i, j) = 255; 
      } 
     } 
    } 

    std::cout << pixels; 

    return 0; 
} 
+0

Um ein wenig mehr Informationen über Char und Uchar zu geben, hier ist ein Code-Snippet. Es zeigt, dass das Zuweisen von 255 zu einem vorzeichenbehafteten Zeichen seinen Wert auf -1 setzt (alle Bits werden auf hoch gesetzt), und das Zuweisen von 255 zu einem vorzeichenlosen Zeichen setzt seinen Wert auf 255. http://cpp.sh/5wjwp – Hill

+0

Danke für Ihre Hilfe, aber ich benutze die 'Mat' nicht direkt. Ich habe ein Bild mit dieser 'Mat' generiert und lade dieses Bild über' imread'. Muss ich das Bild dann auch mit einer Matte als 'uchar' erzeugen? Ich dachte, es würde keinen großen Unterschied machen ... – Lucy

+0

Wenn Sie das Bild mit 'imread (..., IMREAD_GRAYSCALE) laden, wird das Bild nicht den Typ' CV_8UC1', d. H. 'Uchar'. Und ja, Sie müssen die Matte mit dem richtigen Typ erzeugen. Mat mit Float-Typ sollte Werte im Bereich [0,1] haben, um korrekt von Imread und Imwrite behandelt zu werden. – Miki