无法从网络摄像头检测形状

时间:2016-09-16 00:54:44

标签: opencv shape detect rectangles

我想找到有多少顶点,并根据椎体的数量来确定形状。到目前为止,我已经能够通过使用' 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. vector contoursPoly(contours.size());
  2. approxPolyDP(Mat(contours [i]),contoursPoly,arcLength(Mat(contours [i])* 0.01,true),true);
  3. 以下是该计划的图片..

    enter image description here

    编辑2:

    感谢您的评论,我已将此部分添加到我的代码中: Mat contourOutput = threshimg.clone();

    我最近得到了这个......

    enter image description here

    但仍有问题。它没有绘制轮廓,这就是为什么无法检测形状。

    编辑3:我也做了我想要的Hough Lines,结果如下:

    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来确定我的目的并确定它有多少个顶点。

2 个答案:

答案 0 :(得分:0)

按轮廓查找形状取决于轮廓没有被某些东西打破(如示例中的拇指)。

更强大的替代方法是使用霍夫变换来查找线条(或线段),然后检查哪些线条相交以形成正方形/矩形。

如果你想使用轮廓,我会在一个循环中运行approxPolyDP,增加近似因子,直到得到一个有4个点的轮廓 - 或者它失败。

答案 1 :(得分:0)

我不确定,但我认为在你进行阈值处理之后(以及在findContour()之前),你需要进行边缘检测,例如使用Canny边缘检测器:

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

关于canny的文档是here