2012-04-25 16 views
9

Objekt innerhalb Bildes zu isolieren, habe ich ein Bild wie:OpenCV 2.3 C - Wie

source

Ich mag die schwarzen Zeilen und Spalten um die Nummer zu entfernen. So wollen ich, dass das Ergebnis:

output

ich versuche dies:

void findX(IplImage* imgSrc,int* min, int* max){ 
    int i; 
    int minFound=0; 
    CvMat data; 
    CvScalar maxVal=cvRealScalar(imgSrc->width * 255); 
    CvScalar val=cvRealScalar(0); 
    //For each col sum, if sum < width*255 then we find the min 
    //then continue to end to search the max, if sum< width*255 then is new max 
    for (i=0; i< imgSrc->width; i++){ 
     cvGetCol(imgSrc, &data, i); 
     val= cvSum(&data); 
     if(val.val[0] < maxVal.val[0]){ 
      *max= i; 
      if(!minFound){ 
       *min= i; 
       minFound= 1; 
      } 
     } 
    } 
} 

void findY(IplImage* imgSrc,int* min, int* max){ 
    int i; 
    int minFound=0; 
    CvMat data; 
    CvScalar maxVal=cvRealScalar(imgSrc->width * 255); 
    CvScalar val=cvRealScalar(0); 
    //For each col sum, if sum < width*255 then we find the min 
    //then continue to end to search the max, if sum< width*255 then is new max 
    for (i=0; i< imgSrc->height; i++){ 
     cvGetRow(imgSrc, &data, i); 
     val= cvSum(&data); 
     if(val.val[0] < maxVal.val[0]){ 
      *max=i; 
      if(!minFound){ 
       *min= i; 
       minFound= 1; 
      } 
     } 
    } 
} 
CvRect findBB(IplImage* imgSrc){ 
    CvRect aux; 
    int xmin, xmax, ymin, ymax; 
    xmin=xmax=ymin=ymax=0; 

    findX(imgSrc, &xmin, &xmax); 
    findY(imgSrc, &ymin, &ymax); 

    aux=cvRect(xmin, ymin, xmax-xmin, ymax-ymin); 

    //printf("BB: %d,%d - %d,%d\n", aux.x, aux.y, aux.width, aux.height); 

    return aux; 

} 

So verwende ich:

IplImage *my_image = cvLoad.... 
CvRect bb = findBB(my_image); 
IplImage *new_image = cvCreateImage(cvSize(bb.width,bb.height), my_image->depth, 1); 
cvShowImage("test",new_image); 

es nicht gut funktioniert, weil ich versuche, um zu prüfen, ob in einem neuen Bild schwarze Zeilen oder Spalten vorhanden sind und diese vorhanden sind. Was kann ich tun? kann mir jemand helfen?

+0

Ihr Bild hat nur eine Nummer, also bin ich mir nicht sicher, was Sie mit schwarzen Zeilen und Spalten "rund" die Zahl meinen. – karlphillip

+0

sorry für mein Englisch wieder .. für "rund" ich meine die Zeilen und Spalten mit allen Wert schwarz (0) in der Nähe der Nummer – JackTurky

+0

Humm .. ich denke, Sie sprechen auf der Pixel-Ebene. Denken Sie jetzt darüber nach, wenn Sie dieses Bild umkehren, wird alles, was schwarz ist, weiß und die Zahl selbst schwarz. Wäre das nicht besser? – karlphillip

Antwort

23

Eine Möglichkeit, es zu tun ist, einfach the bounding box technique ausführen um die Ziffer zu erkennen, wie durch das Bild unten (sorry für mein Englisch!):

enter image description here

Da Ihr Bild bereits die Begrenzungs verarbeitet wird Box-Technik, die ich benutze, ist viel einfacher.

Nach dieser Prozedur, alles, was Sie wirklich tun müssen, um den ROI festgelegt ist (Region of Interest) des ursprünglichen Bildes auf dem durch die Box definiert die Ernte Wirkung zu erzielen und isolieren, um das Objekt:

enter image description here

Beachten Sie, dass in dem resultierenden Bild eine zusätzliche Zeile/Spalte von Pixeln in dem Rahmen nicht weiß ist. Nun, sie sind auch nicht schwarz. Das liegt daran, dass ich keine Schwellenwertmethode ausgeführt habe, um das Bild in Schwarzweiß zu digitalisieren. Der folgende Code demonstriert die Bounding-Box-Technik, die auf einer Graustufenversion des Bilds ausgeführt wird.

Dies ist so ziemlich die Roadmap, um zu erreichen, was Sie wollen. Für Bildungszwecke teile ich den Code, den ich mit der C++ - Schnittstelle von OpenCV geschrieben habe. Ich bin sicher, dass Sie in der Lage sind, es in die C-Schnittstelle zu konvertieren.

#include <cv.h> 
#include <highgui.h> 

#include <vector> 


int main(int argc, char* argv[]) 
{ 
    cv::Mat img = cv::imread(argv[1]); 

    // Convert RGB Mat to GRAY 
    cv::Mat gray; 
    cv::cvtColor(img, gray, CV_BGR2GRAY); 

    // Store the set of points in the image before assembling the bounding box 
    std::vector<cv::Point> points; 
    cv::Mat_<uchar>::iterator it = gray.begin<uchar>(); 
    cv::Mat_<uchar>::iterator end = gray.end<uchar>(); 
    for (; it != end; ++it) 
    { 
     if (*it) points.push_back(it.pos()); 
    } 

    // Compute minimal bounding box 
    cv::RotatedRect box = cv::minAreaRect(cv::Mat(points)); 

// Draw bounding box in the original image (debug purposes) 
//cv::Point2f vertices[4]; 
//box.points(vertices); 
//for (int i = 0; i < 4; ++i) 
//{ 
     //cv::line(img, vertices[i], vertices[(i + 1) % 4], cv::Scalar(0, 255, 0), 1, CV_AA); 
//} 
//cv::imshow("box", img); 
//cv::imwrite("box.png", img); 

    // Set Region of Interest to the area defined by the box 
    cv::Rect roi; 
    roi.x = box.center.x - (box.size.width/2); 
    roi.y = box.center.y - (box.size.height/2); 
    roi.width = box.size.width; 
    roi.height = box.size.height; 

    // Crop the original image to the defined ROI 
    cv::Mat crop = img(roi); 
    cv::imshow("crop", crop); 

    cv::imwrite("cropped.png", crop); 
    cvWaitKey(0); 

    return 0; 
} 
+0

Wie kann ich Std :: Vector Punkte konvertieren; cv :: Mat_ :: Iterator es = grau.beginne (); cv :: Mat_ :: Iterator Ende = grau.end (); für (; it! = Ende; ++ es) { if (* it) points.push_back (it.pos()); } // Berechnen Sie die minimale Bounding-Box cv :: RotatedRect-Box = cv :: minAreaRect (cv :: Mat (Punkte)); in c-schnittstelle? – JackTurky

+0

Es ist am besten zu verstehen, was jeder von diesen tut: Der erste Teil fügt einfach die Koordinaten von Pixeln, die nicht schwarz sind, zu einem Vektor von Punkten hinzu. Über den zweiten Teil ersetzt 'cv :: RotatedRect' die alte' CvBox2D' (was Sie brauchen). – karlphillip

+0

Wie kann ich die Anzahl der Pixel kennen, die nicht schwarz sind, die Nummer verwenden, um einen Vektor zuzuordnen? – JackTurky