Opencv Can';无法从网络摄像头中检测形状

Opencv Can';无法从网络摄像头中检测形状,opencv,shape,detect,rectangles,Opencv,Shape,Detect,Rectangles,我想找出有多少个顶点,并通过顶点的数量来确定形状。到目前为止,我已经能够通过使用“Houghcirle”来检测圆是否存在,但我无法处理矩形、正方形或三角形 这是代码,但我做不到 // declerations vector<vector<Point>> contoursPoly(contours.size()); vector<Rect> boundRect(contours.size()); vector<vector<Point>>

我想找出有多少个顶点,并通过顶点的数量来确定形状。到目前为止,我已经能够通过使用“Houghcirle”来检测圆是否存在,但我无法处理矩形、正方形或三角形

这是代码,但我做不到

// 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;
//偏差
向量轮廓(courtous.size());
向量boundRect(contours.size());
矢量等值线;
向量层次;
Mat轮廓仪;
垫架,出;
//用于网络摄像头
视频捕获vcap(0);
对于(;;){
vcap.read(frame);//显示
CVT颜色(帧、输出、CV_BGR2GRAY);//将BGR转换为灰度
//固定噪音
GaussianBlur(out,out,Size(9,9),2);
阈值(out,out,200255,CV_THRESH_BINARY_INV|CV_THRESH_OTSU);
查找轮廓(向外、轮廓、层次、CV_RETR_外部、CV_CHAIN_近似值_NONE);//查找轮廓
对于(int i=0;i
编辑:

我做了一些改变

  • 向量轮廓(courtous.size())
  • 近似多边形(Mat(等高线[i])、等高线多边形、弧长(Mat(等高线[i])*0.01,真)、真)
  • 这是节目中的图片

    编辑2:

    多亏了这些评论,我在代码中添加了以下部分: Mat contourOutput=threshimg.clone()

    我最近收到了这个

    但是仍然存在一个问题,它不能绘制轮廓,这就是为什么不能检测形状

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

    代码如下:

    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;
    }
    
    intmain(){
    视频捕获vcap(0);
    垫灰色、框架、遮罩、外表面、外表面;
    矢量等值线;
    矢量控制;
    向量层次;
    旋转校正;
    点2f顶点[4];
    对于(;;){
    vcap.read(帧);
    CVT颜色(边框、灰色、CV_BGR2灰色);
    高斯模糊(灰色,灰色,大小(9,9),1);
    阈值(灰色、遮罩、220、255、CV_阈值_二进制);
    Mat-contoursOut=mask.clone();
    findContours(轮廓线、轮廓线、CV_-RETR_外部、CV_-CHAIN_-About_-NONE);
    out=Mat::零(轮廓尺寸(),CV_8UC3);
    对于(int i=0;i

    第二段代码中是否有不合逻辑的地方或错误?实际上,我想通过使用approxPolyDP实现我的目的,并确定有多少个顶点。

    通过轮廓查找形状依赖于轮廓没有被某些东西破坏(如示例中的拇指)

    更可靠的替代方法是使用hough变换查找直线(或线段),然后检查哪些直线相交以形成正方形/矩形


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

    通过轮廓查找形状依赖于轮廓没有被什么东西破坏(比如示例中的拇指)

    更可靠的替代方法是使用hough变换查找直线(或线段),然后检查哪些直线相交以形成正方形/矩形


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

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

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

    canny的文档是。

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

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

    有关canny的文档是。

    请尝试
    approxPolyDP(Mat(轮廓[i]),轮廓[i],0.01*arcLength(Mat(轮廓[i]),true),true);
    谢谢您的回复,但它不起作用。然后请提供一些示例图像。来源、阈值化后的二进制图像和检测到的轮廓并检查轮廓[i]。大小()它也不起作用。我提供了一些图像。请尝试
    approxPolyDP(Mat(轮廓[I]),轮廓[I],0.01*arcLength(Mat(轮廓[I]),true),true);
    谢谢你的回复,但它不起作用。然后请提供一些示例图像。它们的来源,阈值化后的二进制图像和检测到的轮廓,并检查轮廓[I]。size()它也不起作用。我提供了图像。你能检查编辑3吗?你能检查编辑3吗?它仍然不能绘制轮廓。我认为在for循环中,你应该测试轮廓[I]。size()不是轮廓。size()?它仍然不能绘制轮廓。我想在for循环中,你应该测试轮廓[I]。size()不是轮廓。size()?