zoukankan      html  css  js  c++  java
  • 28、【opencv入门】轮廓查找与绘制(6)——外接圆、椭圆拟合、逼近多边形曲线、计算轮廓面积及长度、提取不规则轮廓

    一、轮廓最小外接圆---minEnclosingCircle()

    1 CV_EXPORTS_W void minEnclosingCircle(InputArray points, CV_OUT Point2f& center, CV_OUT float& radius);

      points: 输入的二维点集, 可以填Mat类型或std::vector

      center: Point2f&类型的center, 圆的输出圆心

      radius: float&类型, 表示圆的输出半径

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

    二、轮廓椭圆拟合---fitEllipse()

    1 CV_EXPORTS_W RotatedRect fitElipse(InputArray points);

      points: 输入的二维点集, 可以填Mat类型或std::vector

      返回值: RotatedRect类旋转矩形对象

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

    三、逼近多边形曲线---approxPolyDP()

    1 CV_EXPORTS_W void approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed);

      curve: 输入的二维点集, 可以填Mat类型或std::vector

      approxCurve: 多边形逼近的结果, 其类型和输入二维点集类型一致

      epsilon: 逼近的精度, 为原始曲线和近似曲线间的最大值

      closed: 如果其为真, 则近似的曲线为封闭曲线, 否则近似的曲线不封闭

     1 //逼近多边形曲线
     2 #include "opencv2/opencv.hpp"
     3 using namespace cv;
     4 
     5 int main() 
     6 {
     7     Mat srcImg = imread("2.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_INV);
    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     vector<vector<Point>> contours_poly(contours.size());
    22 
    23     for (int i = 0; i<contours.size(); i++)
    24     {
    25         approxPolyDP(Mat(contours[i]), contours_poly[i],15, true);//true曲线封闭,反之不封闭
    26         drawContours(dstImg, contours, i, Scalar(0, 255, 0), 2, 8);//绘制轮廓
    27         drawContours(dstImg2, contours_poly, i, Scalar(0, 255, 255), 2, 8);  //绘制多边形逼近
    28     }
    29     imshow("dst", dstImg);
    30     imshow("approx", dstImg2);
    31 
    32     waitKey(0);
    33     return 0;
    34 }

     四、计算轮廓面积---contourArea()

    1 CV_EXPORTS_W double contourArea(InputArray contour, bool oriented=false);

      contour: 输入的二维点集或轮廓, 可以填Mat类型或std::vector

      oriented: 默认值false, 表示返回面积为绝对值, 负责带符号

      返回值: double类型返回轮廓面积

     五、计算轮廓长度---arcLength()

    1 CV_EXPORTS_W double arcLength(InputArray curve, bool closed);

      curve: 输入的二维点集, 可以填Mat类型或std::vector

      colsed: 用于指示曲线是否封闭的标识符, 默认值true, 表示曲线封闭 

      返回值: double类型返回轮廓长度

    注:contourArea()&& arcLength()可用于轮廓删选 

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

    六、提取不规则轮廓

     1 //提取不规则轮廓
     2 #include "opencv2/opencv.hpp"
     3 
     4 using namespace cv;
     5 
     6 int main() 
     7 {
     8     Mat srcImg = imread("2.jpg");
     9     imshow("src", srcImg);
    10     Mat dstImg = srcImg.clone();  //原图备份
    11     Mat tempImg = srcImg.clone();  //原图备份
    12     Mat tempImg2(srcImg.size(), CV_8UC3, Scalar::all(0));  //定义全黑的和原图一样大小的图像
    13     Mat draw(srcImg.size(), CV_8UC3, Scalar::all(0)); 
    14     Mat tempImg3(srcImg.size(), CV_8UC3, Scalar::all(0)); 
    15 
    16     GaussianBlur(srcImg, srcImg, Size(3, 3), 0, 0);
    17     cvtColor(srcImg, srcImg, CV_BGR2GRAY);
    18     threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY); //二值化
    19     imshow("threshold", srcImg);
    20 
    21     vector<vector<Point>> contours;
    22     vector<Vec4i> hierarcy;
    23     findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
    24     while (1)
    25     {
    26         for (int i = 0; i<contours.size(); i++)
    27         {
    28             tempImg2.copyTo(draw);  //每次进入将draw清空为全黑
    29             tempImg2.copyTo(tempImg3); 
    30             //drawContours(dstImg, contours, i, Scalar(0, 255, 0), 5, 8);    
    31             drawContours(draw, contours, i, Scalar(255, 255, 255), -1, 8);
    32             Mat mask;  //定义掩码
    33             cvtColor(draw, mask, CV_BGR2GRAY);
    34             tempImg.copyTo(tempImg3, mask);  //将tempImg 复制到tempImg3(只有mask部分被复制)
    35             imshow("draw", draw);
    36             imshow("result", tempImg3);
    37             char key = waitKey();
    38             if (key == 27)  //按下Esc键跳出for循环
    39                 break;
    40         }
    41         break;
    42     }
    43     return 0;
    44 }
  • 相关阅读:
    linux系统--磁盘管理命令(二)
    linux系统--磁盘管理命令(一)
    linux系统--用户和用户组
    linux4.10.8 内核移植(四)---字符设备驱动_led驱动程序
    linux4.10.8 内核移植(三)---裁剪内核
    linux4.10.8 内核移植(二)---初步裁剪、分区修改和文件系统
    Linux 4.10.8 根文件系统制作(三)---制作yaffs文件系统
    Kotlin的面向对象入门
    Python 中的GIL
    python 虚拟环境的 安装与 使用 和修改为豆瓣源
  • 原文地址:https://www.cnblogs.com/Long-w/p/9668611.html
Copyright © 2011-2022 走看看