算法介绍: 对图像中的任意多边形进行检测
输入: 图像,多边形逼近精度,多边形最小面积
输出: 检测出的多边形角点
函数声明:
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;
}