2016-09-16 87 views
1

我想查找有多少個頂點存在,並根據頂點的數量來確定形狀。到目前爲止,我已經能夠檢測到一個圓是否存在或不使用'HoughCircle',但我無法應付矩形,方形或三角形。無法檢測網絡攝像頭的形狀

這是代碼,但我做不到。

// 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; 

編輯:

我已經做了一些改變..

  1. 矢量contoursPoly(contours.size()); (Mat(contour [i]),contoursPoly,arcLength(Mat(contour [i])* 0.01,true),true);

,這裏是從程序中的圖像..

enter image description here

編輯2:

感謝的意見,我已經添加了這部分我的代碼: 墊contourOutput = threshimg.clone();

,我已經得到了這個最近..

enter image description here

但仍然是一個問題。它不繪製輪廓,這就是爲什麼無法檢測形狀。

編輯3:我也通過霍夫線來完成我想要的東西,這裏是結果:

enter image description here

這是代碼:

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; 
} 

是否有任何不合理的事物或第二個代碼中的錯誤?實際上,我想通過使用approxPolyDP來實現我的目的,並確定有多少個頂點。

+0

嘗試使用'approxPolyDP(Mat(輪廓[i]),輪廓Poly [i],0。01 * arcLength(Mat(contour [i]),true),true);' – PSchn

+0

感謝您的回覆,但沒有奏效。 – PIC16F84A

+0

然後請提供一些示例圖像。 Rhe源,閾值和檢測到的輪廓後的二進制文件 – PSchn

回答

0

通過輪廓查找形狀依賴於輪廓不被某物(如示例中的拇指)破壞。

更強大的替代方法是使用hough變換來查找線條(或線段),然後檢查哪些線相交以形成正方形/矩形。

如果你想使用輪廓,我會在一個循環中運行approxPolyDP,增加近似因子,直到你得到一個有4點的輪廓 - 否則失敗。

+0

你可以檢查編輯3嗎? – PIC16F84A

0

我不知道,但我認爲,以後你做的閾值(和之前的findContour()),您需要使用Canny邊緣檢測做邊緣檢測,例如:

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

關於canny的文檔是here

+0

它仍然無法繪製輪廓。 – PIC16F84A

+0

我想在for循環中,你應該測試contoursPoly [i] .size()而不是contoursPoly.size()? – centralcmd