(opencv)任意多边形检测

算法介绍: 对图像中的任意多边形进行检测
输入: 图像,多边形逼近精度,多边形最小面积
输出: 检测出的多边形角点
函数声明:

vector<vector<Point>> polygonDetect(Mat&,double epsilon,int minAcreage); //多边形检测

调用:

Mat matin=camera->read(); //视频流读入
vector<vector<Point>> polygonDetectRet=polygonDetect(matin,8,2000);
for(int i=0;i<polygonDetectRet.size();i++)
    for(int j=0;j<polygonDetectRet[i].size();j++){
        circle(matin,polygonDetectRet[i][j],4,Scalar(0,0,255),-1);
    }
imshow("多边形检测结果",matin);

效果图:
在这里插入图片描述

源码:

//多边形检测
vector<vector<Point>> polygonDetect(Mat& srcImg,double epsilon,int minAcreage)
{
    //彩色图转灰度图
    Mat src_gray;
    cvtColor(srcImg, src_gray, CV_BGR2GRAY);
    imshow("1.彩色图转灰度图", src_gray);
    //Otsu自动阈值
    Mat threshold_output;
    threshold(src_gray, threshold_output, 0, 255, THRESH_BINARY|THRESH_OTSU); //Otsu 二值化
    imshow("2.二值化(Otsu自动阈值)", threshold_output);
    //滤波
    Mat threshold_output_copy = threshold_output.clone();
    Mat element = getStructuringElement(MORPH_ELLIPSE, Size(1, 1)); //卷积核大小可变,推荐1或3,此处为1
    morphologyEx(threshold_output_copy, threshold_output_copy, MORPH_OPEN, element); //开运算
    morphologyEx(threshold_output_copy, threshold_output_copy, MORPH_CLOSE, element); //闭运算
    imshow("3.开运算+闭运算", threshold_output_copy);
    //边缘检测
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    Mat canny_output;
    Canny( threshold_output_copy, canny_output, 1, 3, 7,true );  //Canny检测
    imshow("4.Canny边缘检测", canny_output);
    //轮廓查找
    Mat image=canny_output.clone();
    findContours(image,contours,hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point());
    Mat Contours=Mat::zeros(image.size(),CV_8UC1);  //绘制
    //contours[i]代表的是第i个轮廓,contours[i].size()代表的是第i个轮廓上所有的像素点数
    for(int i=0;i<contours.size();i++)
        for(int j=0;j<contours[i].size();j++){
            Point P=Point(contours[i][j].x,contours[i][j].y);
            Contours.at<uchar>(P)=255;
        }
    imshow("5.findContours轮廓提取",Contours);
    Mat mat6=Contours.clone();
    cvtColor(mat6, mat6, CV_GRAY2BGR);
    vector<vector<Point>> contours_poly;
    for(int i=0;i<contours.size();i++){
        double acreage= contourArea(contours[i], true);
        if(acreage>minAcreage) { //面积筛选
            vector<Point> contourspoly;
            approxPolyDP(contours[i], contourspoly, epsilon, true);//用指定精度逼近多边形曲线
            contours_poly.push_back(contourspoly);
        }
    }
    return contours_poly;
}
发布了18 篇原创文章 · 获赞 5 · 访问量 6682

猜你喜欢

转载自blog.csdn.net/Sun_tian/article/details/104221658