opencv学习之路(27)、轮廓查找与绘制(六)——外接圆、椭圆拟合、逼近多边形曲线、计算轮廓面积及长度、提取不规则轮廓

一、最小外接圆

 1 #include "opencv2/opencv.hpp"
 2 #include<iostream>
 3 using namespace std;
 4 using namespace cv;
 5 
 6 void main() {
 7     Mat srcImg = imread("E://10.png");
 8     imshow("src", srcImg);
 9     Mat dstImg = srcImg.clone();
10     GaussianBlur(srcImg, srcImg, Size(3, 3), 0, 0);
11     cvtColor(srcImg, srcImg, CV_BGR2GRAY);
12     Canny(srcImg, srcImg, 100, 200);
13     imshow("Canny", srcImg);
14 
15     //查找轮廓
16     vector<vector<Point>> contours;
17     vector<Vec4i> hierarcy;
18     findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
19     cout << "num=" << contours.size() << endl;
20 
21     Point2f center;  //定义圆中心坐标
22     float radius;  //定义圆半径
23     for (int i = 0; i<contours.size(); i++)  //依次遍历每个轮廓
24     {
25         minEnclosingCircle(Mat(contours[i]), center, radius);
26         drawContours(dstImg, contours, i, Scalar(0, 0, 255), 2, 8);
27         circle(dstImg, center, radius, Scalar(0, 255, 0), 2, 8);  //绘制第i个轮廓的最小外接圆
28     }
29     imshow("dst", dstImg);
30 
31     waitKey(0);
32 }

 二、椭圆拟合

 1 #include "opencv2/opencv.hpp"
 2 using namespace cv;
 3 
 4 void main() {
 5     Mat srcImg = imread("E://10.png");
 6     imshow("src", srcImg);
 7     Mat dstImg = srcImg.clone();
 8     GaussianBlur(srcImg, srcImg, Size(3, 3), 0, 0);
 9     cvtColor(srcImg, srcImg, CV_BGR2GRAY);
10     Canny(srcImg, srcImg, 100, 200);
11     imshow("Canny", srcImg);
12 
13     //查找轮廓
14     vector<vector<Point>> contours;
15     vector<Vec4i> hierarcy;
16     findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
17 
18     vector<RotatedRect> box(contours.size());
19     Point2f rect[4];
20     for (int i = 0; i<contours.size(); i++)
21     {
22         box[i] = fitEllipse(Mat(contours[i]));
23         //ellipse(dstImg, box[i].center, Size(box[i].size.width/2, box[i].size.height/2), box[i].angle, 0, 360, Scalar(0, 255, 0), 2, 8);
24         ellipse(dstImg, box[i], Scalar(0, 255, 0), 2, 8);
25     }
26     imshow("dst", dstImg);
27 
28     waitKey(0);
29 }

三、逼近多边形曲线

 1 #include "opencv2/opencv.hpp"
 2 using namespace cv;
 3 
 4 void main() {
 5     Mat srcImg = imread("E://02.jpg");
 6     imshow("src", srcImg);
 7     Mat dstImg = srcImg.clone();
 8     Mat dstImg2(srcImg.size(), CV_8UC3, Scalar::all(0));//全黑图像
 9 
10     GaussianBlur(srcImg, srcImg, Size(3, 3), 0, 0);
11     cvtColor(srcImg, srcImg, CV_BGR2GRAY);
12     //Canny(srcImg, srcImg, 100, 200);
13     threshold(srcImg, srcImg, 200, 255, CV_THRESH_BINARY_INV);
14     imshow("threshold", srcImg);
15 
16     vector<vector<Point>> contours;
17     vector<Vec4i> hierarcy;
18     findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
19     vector<vector<Point>> contours_poly(contours.size());
20 
21     for (int i = 0; i<contours.size(); i++)
22     {
23         approxPolyDP(Mat(contours[i]), contours_poly[i],15, true);//true曲线封闭,反之不封闭
24         drawContours(dstImg, contours, i, Scalar(0, 255, 0), 2, 8);//绘制轮廓
25         drawContours(dstImg2, contours_poly, i, Scalar(0, 255, 255), 2, 8);  //绘制多边形逼近
26     }
27     imshow("dst", dstImg);
28     imshow("approx", dstImg2);
29 
30     waitKey(0);
31 }

 四、计算轮廓面积及长度(可用于轮廓筛选

 1 #include "opencv2/opencv.hpp"
 2 #include<iostream>
 3 using namespace std;
 4 using namespace cv;
 5 
 6 void main() {
 7     Mat srcImg = imread("E://33.jpg");
 8     imshow("src", srcImg);
 9     Mat dstImg = srcImg.clone();
10     Mat dstImg2(srcImg.size(), CV_8UC3, Scalar::all(0));
11 
12     GaussianBlur(srcImg, srcImg, Size(3, 3), 0, 0);
13     cvtColor(srcImg, srcImg, CV_BGR2GRAY);
14     //Canny(srcImg, srcImg, 100, 200);
15     threshold(srcImg, srcImg, 200, 255, CV_THRESH_BINARY);
16     imshow("threshold", srcImg);
17 
18     vector<vector<Point>> contours;
19     vector<Vec4i> hierarcy;
20     findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
21     cout << "num=" << contours.size() << endl;
22 
23     for (int i = 0; i<contours.size(); i++)
24     {
25         double area = contourArea(contours[i]);//计算第i个轮廓的面积
26         cout<<"area--"<<i<<"---"<<area<<endl;
27 
28         double length = arcLength(contours[i], true);
29         cout << "length--" << i << "---" << length << endl;
30         //if(area>10000)  //面积大约1W
31         //if(area> 100 && area<300)
32 
33         if (length<300 && area>300)  
34             drawContours(dstImg, contours, i, Scalar(0, 0, 255), 2, 8);
35     }
36     imshow("dst", dstImg);
37     waitKey(0);
38 }

五、提取不规则轮廓

 1 #include "opencv2/opencv.hpp"
 2 using namespace cv;
 3 
 4 void main() {
 5     Mat srcImg = imread("E://220.jpg");
 6     imshow("src", srcImg);
 7     Mat dstImg = srcImg.clone();  //原图备份
 8     Mat tempImg = srcImg.clone();  //原图备份
 9     Mat tempImg2(srcImg.size(), CV_8UC3, Scalar::all(0));  //定义全黑的和原图一样大小的图像
10     Mat draw(srcImg.size(), CV_8UC3, Scalar::all(0)); 
11     Mat tempImg3(srcImg.size(), CV_8UC3, Scalar::all(0)); 
12 
13     GaussianBlur(srcImg, srcImg, Size(3, 3), 0, 0);
14     cvtColor(srcImg, srcImg, CV_BGR2GRAY);
15     threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY); //二值化
16     imshow("threshold", srcImg);
17 
18     vector<vector<Point>> contours;
19     vector<Vec4i> hierarcy;
20     findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
21     while (1)
22     {
23         for (int i = 0; i<contours.size(); i++)
24         {
25             tempImg2.copyTo(draw);  //每次进入将draw清空为全黑
26             tempImg2.copyTo(tempImg3); 
27             //drawContours(dstImg, contours, i, Scalar(0, 255, 0), 5, 8);    
28             drawContours(draw, contours, i, Scalar(255, 255, 255), -1, 8);
29             Mat mask;  //定义掩码
30             cvtColor(draw, mask, CV_BGR2GRAY);
31             tempImg.copyTo(tempImg3, mask);  //将tempImg 复制到tempImg3(只有mask部分被复制)
32             imshow("draw", draw);
33             imshow("result", tempImg3);
34             char key = waitKey();
35             if (key == 27)  //按下Esc键跳出for循环
36                 break;
37         }
38         break;
39     }
40 }

原文地址:https://www.cnblogs.com/little-monkey/p/7469354.html