2016-09-16 2 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; 

EDIT:

Я сделал некоторые изменения ..

  1. вектор contoursPoly (contours.size());
  2. approxPolyDP (Mat (контуры [i]), контурыPoly, arcLength (Mat (контуры [i]) * 0.01, true), true);

и здесь изображения из программы ..

enter image description here

EDIT 2:

Благодаря комментариям, я добавил эту часть моего кода: Mat contourOutput = threshimg.clone();

и я получил это в последнее время ..

enter image description here

Но есть еще проблема. Он не рисует контуры, поэтому не может обнаружить формы.

EDIT 3: Кроме того, я сделал то, что я хочу от Hough линий и вот результат:

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 (контуры [i]), true), true); ' – PSchn

+0

Спасибо за ваш ответ, но это не сработало. – PIC16F84A

+0

Затем, пожалуйста, предоставьте несколько образцовых изображений. Rhe, двоичный inage после порога и обнаруженных контуров – PSchn

ответ

0

Поиск фигур по контурам основывается на контуре, не сломанной чем-то (например, большим пальцем в примере).

Более надежной альтернативой могло бы быть использование преобразования hough для поиска линий (или сегментов линии), а затем проверить, какие линии пересекаются, чтобы сформировать квадраты/прямоугольники.

Если вы хотите использовать контуры, я буду запускать approxPolyDP в цикле, увеличивая коэффициент аппроксимации, пока вы не получите контур с 4 очками - или он не сработает.

+0

Не могли бы вы проверить EDIT 3? – PIC16F84A

0

Я не уверен, но я думаю, что после того, как вы сделаете пороговое (и до findContour()), вам нужно сделать обнаружение края, например, с помощью пограничного детектора Канне:

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

Документация о canny - here.

+0

Он все еще не может рисовать контуры. – PIC16F84A

+0

Я думаю, что в цикле for вы должны проверить контурыPoly [i] .size() not contoursPoly.size()? – centralcmd

Смежные вопросы