2016-09-16 4 views
1

Ich möchte herausfinden, wie viele Eckpunkte existieren und die Form anhand der Anzahl der Vertices bestimmen. Bis jetzt konnte ich erkennen, ob ein Kreis existiert oder nicht, indem ich 'HoughCircle' benutze, aber ich komme nicht mit Rechteck, Quadrat oder Dreieck zurecht.Kann keine Shapes von der Webcam erkennen

Hier ist der Code, aber ich konnte es nicht tun.

// declerations 
vector<vector<Point>> contoursPoly(contours.size()); 
vector<Rect> boundRect(contours.size()); 
vector<vector<Point>> contours; 
vector<Vec4i> hierarchy; 
Mat contourimg; 
Mat frame, out; 

// for webcam 
VideoCapture vcap(0); 

for (;;){ 

    vcap.read(frame); // display 
    cvtColor(frame, out, CV_BGR2GRAY); // convert BGR to GRAY scale 

    // fix noises 
    GaussianBlur(out, out, Size(9, 9), 2); 
    threshold(out,out,200,255,CV_THRESH_BINARY_INV | CV_THRESH_OTSU); 

    findContours(out, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); // find contours 

    for (int i = 0; i < contours.size(); i++) 
    { 
     approxPolyDP(Mat(contours[i]), contoursPoly[i], 3, true); // find the number of vertecies 

     if (contoursPoly.size() == 4) // it should be a quadrilateral 
     { 
      boundRect[i] = boundingRect(contoursPoly[i]); 
      drawContours(frame, contours, i, Scalar(0, 0, 255), CV_FILLED, 8, hierarchy, 0, Point()); 
     } 

     if (contoursPoly.size() == 3) // it should be triange 
     { 
      drawContours(frame, contours, i, Scalar(0, 0, 255), CV_FILLED, 8, hierarchy, 0, Point()); 
     } 

    imshow("test", frame); 
    if (waitKey(30) == 27) break; 

EDIT:

ich einige Änderungen vorgenommen haben ..

  1. Vektor contoursPoly (contours.size());
  2. approxPolyDP (Mat (Konturen [i]), contoursPoly, arcLength (Mat (Konturen [i]) * 0.01, true), true);

und hier die Bilder aus dem Programm ..

enter image description here

EDIT 2:

Dank der Kommentare, ich diesen Teil meiner Code hinzugefügt haben: Mat contourOutput = threshimg.clone();

und ich habe das vor kurzem bekam ..

enter image description here

Aber es ist immer noch ein Problem. Es zeichnet nicht die Konturen, deshalb können Formen nicht erkannt werden.

EDIT 3: Ich habe auch, was ich will von Hough-Linien und hier ist das Ergebnis getan:

enter image description here

Dies ist der Code:

int main(){ 

    VideoCapture vcap(0); 
    Mat gray, frame, mask, out, trackbarimg; 

    vector<vector<Point>> contours; 
    vector<Point> contPoly; 
    vector<Vec4i> hierarchy; 
    RotatedRect rrect; 
    Point2f vertices[4]; 

    for (;;){ 

     vcap.read(frame); 
     cvtColor(frame, gray, CV_BGR2GRAY); 
     GaussianBlur(gray,gray,Size(9,9), 1); 
     threshold(gray, mask, 220, 255, CV_THRESH_BINARY); 

     Mat contoursOut = mask.clone(); 
     findContours(contoursOut, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); 

     out = Mat::zeros(contoursOut.size(), CV_8UC3); 

     for (int i = 0; i < contours.size(); i++){ 
      drawContours(out, contours, i, Scalar(0, 255, 0), CV_FILLED, 8, hierarchy, 1, Point()); 
      rrect = minAreaRect(contours[i]); 

      rrect.points(vertices); 
      line(out, vertices[0], vertices[1], cv::Scalar(0, 0, 255)); 
      line(out, vertices[1], vertices[2], cv::Scalar(0, 0, 255)); 
      line(out, vertices[2], vertices[3], cv::Scalar(0, 0, 255)); 
      line(out, vertices[3], vertices[0], cv::Scalar(0, 0, 255)); 
     } 

     imshow("THRESHOLD", mask); 
     imshow("BLUR", gray); 
     imshow("ORIGINAL", frame); 
     imshow("LINES", out); 

     if (waitKey(30) == 27) break; 

    } 
    return 0; 
} 

Gibt es unlogisch Dinge oder Fehler im zweiten Code? Eigentlich möchte ich meinen Zweck erfüllen, indem ich approxPolyDP verwende und festlege, wie viele Scheitelpunkte es gibt.

+0

Versuchen Sie 'approxPolyDP (Mat (Konturen [i]), contoursPoly [i], 0.01 * arcLength (Mat (Konturen [i]), true), true); ' – PSchn

+0

Vielen Dank für Ihre Antwort, aber es hat nicht funktioniert. – PIC16F84A

+0

Dann stellen Sie bitte einige Beispielbilder zur Verfügung. Rhe Quelle, die Binärinage nach der Schwellenwertbildung und die erkannten Konturen – PSchn

Antwort

0

Das Finden von Formen nach Konturen hängt davon ab, dass der Umriss nicht von etwas durchbrochen wird (wie im Beispiel Ihres Daumens). Eine robustere Alternative wäre es, die Hough-Transformation zu verwenden, um Linien (oder Liniensegmente) zu finden und dann zu prüfen, welche Linien sich schneiden, um Quadrate/Rechtecke zu bilden.

Wenn Sie Konturen verwenden möchten, würde ich approxPolyDP in einer Schleife ausführen, den Näherungsfaktor erhöhen, bis Sie eine Kontur mit 4 Punkten erhalten - oder es schlägt fehl.

+0

Könnten Sie EDIT 3 überprüfen? – PIC16F84A

0

Ich bin nicht sicher, aber ich glaube, dass, nachdem Sie tun, um die Schwellwerte (und vor dem findContour()), benötigen Sie eine Kantenerkennung, zum Beispiel zu tun, einen Canny-Algorithmus unter Verwendung von:

void cv::Canny (InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize = 3, bool L2gradient = false) 

Dokumentation auf canny ist here.

+0

Es kann immer noch keine Konturen zeichnen. – PIC16F84A

+0

Ich denke, in der for-Schleife sollten Sie für KonturenPoly [i] .size() nicht KonturenPoly.size() testen? – centralcmd