栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

opencv[c++] findContours()轮廓特征分析大全(求面积、周长、几何矩、质心、凸包、最小外接矩形、最小外接三角形、最小外接椭圆等)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

opencv[c++] findContours()轮廓特征分析大全(求面积、周长、几何矩、质心、凸包、最小外接矩形、最小外接三角形、最小外接椭圆等)

void test_contours_feature()
 {
     cv::Mat src;
       src = cv::imread("feature.png", cv::IMREAD_GRAYSCALE);
       if (src.empty()) {
           cout << "Cannot load image" << endl;
           return;
       }
       cv::imshow("src", src);


       cv::Mat binary;
       cv::threshold(src, binary, 150, 255, cv::THRESH_BINARY_INV);

       cv::Mat k55 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5), cv::Point(-1, -1));
       cv::morphologyEx(binary, binary, cv::MORPH_OPEN, k55, cv::Point(-1, -1), 1);


       cv::namedWindow("binary",cv::WINDOW_NORMAL);
       cv::imshow("binary", binary);


       std::vector > defectContours;
       std::vector hierarchyDefect;
       cv::findContours(binary, defectContours, hierarchyDefect, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);

       cv::Mat contours = cv::Mat(src.size(), CV_8UC3, cv::Scalar(0,0,0));

       cv::Mat drawCenterPos = cv::Mat(src.size(), CV_8UC3, cv::Scalar(0,0,0));
       cv::Mat drawRect = cv::Mat(src.size(), CV_8UC3, cv::Scalar(0,0,0));
       cv::Mat drawHull = cv::Mat(src.size(), CV_8UC3, cv::Scalar(0,0,0));
       cv::Mat drawRotateRect = cv::Mat(src.size(), CV_8UC3, cv::Scalar(0,0,0));
       cv::Mat drawMinEnclosingCircle = cv::Mat(src.size(), CV_8UC3, cv::Scalar(0,0,0));
       cv::Mat drawMinEnclosingTriangle = cv::Mat(src.size(), CV_8UC3, cv::Scalar(0,0,0));
       cv::Mat drawEllipse = cv::Mat(src.size(), CV_8UC3, cv::Scalar(0,0,0));

       std::vector> PolyDPs;
       cv::Mat drawPolyDP = cv::Mat(src.size(), CV_8UC3, cv::Scalar(0,0,0));


       std::vector > hull(defectContours.size());
       for (int i = 0; i < defectContours.size(); i++)
       {
           //轮廓 白色
           cv::drawContours(contours, defectContours, i, cv::Scalar(255,255,255), 1);

           //求面积
           double fArea = cv::contourArea(defectContours[i]);
           qDebug()< boxPts(4);
           rotateRect.points(boxPts.data());

           for (int j = 0; j < 4; j++)
           {
               cv::line(drawRotateRect, boxPts[j], boxPts[(j + 1) % 4], cv::Scalar(128, 128, 0), 1, 8);  //绘制最小外接矩形每条边
           }
           
           //最小外接圆 棕褐色
           cv::Point2f center;
           float fRadius = 0;
           cv::minEnclosingCircle(defectContours[i], center, fRadius);
           cv::circle(drawMinEnclosingCircle, center, fRadius, cv::Scalar(140,180,210),1);

           //最小外界三角形 粉色
           std::vector points;
           cv::minEnclosingTriangle(defectContours[i], points);
           cv::line(drawMinEnclosingTriangle, points[0], points[1], cv::Scalar(193, 182, 255), 1, 8);  //绘制最小外接三角形每条边
           cv::line(drawMinEnclosingTriangle, points[2], points[1], cv::Scalar(193, 182, 255), 1, 8);  //绘制最小外接三角形每条边
           cv::line(drawMinEnclosingTriangle, points[2], points[0], cv::Scalar(193, 182, 255), 1, 8);  //绘制最小外接三角形每条边


           //椭圆 紫罗兰色
           cv::RotatedRect ellipse =  cv::fitEllipse(defectContours[i]);
           cv::ellipse(drawEllipse, ellipse, cv::Scalar(226,43,138));

           //多边形逼近 洋红色
           std::vector PolyDP;
           //cv::Mat PolyDP ;
           cv::approxPolyDP(defectContours[i],PolyDP, 0.5, true);
           PolyDPs.push_back(PolyDP);
           //cv::drawContours(drawPolyDP, PolyDP, 0, cv::Scalar(23,56,234));
           //drawPolyDP += cv::Mat(PolyDP);
       }

       //画多边形逼近
       for(int j = 0; j < PolyDPs.size(); j++)
       {
           cv::drawContours(drawPolyDP, PolyDPs, j, cv::Scalar(255,0,255),1);
       }


       drawCenterPos += contours;
       drawRect += contours;
       drawHull += contours;
       drawRotateRect += contours;
       drawMinEnclosingCircle += contours;
       drawMinEnclosingTriangle += contours;
       drawEllipse += contours;

       cv::namedWindow("contours",cv::WINDOW_NORMAL);
       cv::imshow("contours", contours);

       cv::namedWindow("drawRect",cv::WINDOW_NORMAL);
       cv::imshow("drawRect", drawRect);

       cv::namedWindow("drawHull",cv::WINDOW_NORMAL);
       cv::imshow("drawHull", drawHull);

       cv::namedWindow("drawRotateRect",cv::WINDOW_NORMAL);
       cv::imshow("drawRotateRect", drawRotateRect);

       cv::namedWindow("drawCenterPos",cv::WINDOW_NORMAL);
       cv::imshow("drawCenterPos", drawCenterPos);

       cv::namedWindow("drawMinEnclosingCircle",cv::WINDOW_NORMAL);
       cv::imshow("drawMinEnclosingCircle", drawMinEnclosingCircle);

       cv::namedWindow("drawMinEnclosingTriangle",cv::WINDOW_NORMAL);
       cv::imshow("drawMinEnclosingTriangle", drawMinEnclosingTriangle);

       cv::namedWindow("drawEllipse",cv::WINDOW_NORMAL);
       cv::imshow("drawEllipse", drawEllipse);

       cv::namedWindow("drawPolyDP",cv::WINDOW_NORMAL);
       cv::imshow("drawPolyDP", drawPolyDP);
 }

#include 
#include 
 
using namespace cv;
using namespace std;
 
Mat imgGray, imgBlur, imgCanny, imgDil, imgErode;
//定义一个轮廓处理函数
void getContours(Mat imgDil,Mat img) {
 
	vector> contours;//{ {Point(20,30),Point(50,60)},{}, {}}
	vectorhierarchy;//vector里放置了四个int类型的变量
	findContours(imgDil, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
	//drawContours(img, contours, -1, Scalar(255, 0, 255), 2);
	vector>conPoly(contours.size());
	vector boundRect(contours.size());
	
	for (int i = 0; i < contours.size(); i++)
	{
		int area = contourArea(contours[i]);
		cout << area << endl;//需要正确过滤的面积(过滤噪点)
 
		string objectType;
        //判断形状
		if (area>1000)
		{
			float peri = arcLength(contours[i], true);
			approxPolyDP(contours[i], conPoly[i], 0.02 * peri, true);//找到近似值
			
			cout << conPoly[i].size() << endl;
			boundRect[i] = boundingRect(conPoly[i]);//边界矩形
			
			int objCor = (int)conPoly[i].size();
 
			if (objCor == 3) { objectType = "Tri"; }
			if (objCor == 4) { 
				
				float aspRatio = (float)boundRect[i].width / (float)boundRect[i].height;
				cout << aspRatio << endl;
				if (aspRatio > 0.95 && aspRatio < 1.05) { objectType = "Square"; }
				else { objectType = "Rect"; 
				}
			}
			if (objCor > 4) { objectType = "Circle"; }
 
			drawContours(img, conPoly, i, Scalar(255, 0, 255), 2);//描绘计数轮廓
			rectangle(img, boundRect[i].tl(), boundRect[i].br(), Scalar(0, 255, 0), 5);//绘制边界矩形
			//打印图形的名字
			putText(img, objectType, { boundRect[i].x,boundRect[i].y - 5 }, FONT_HERSHEY_PLAIN, 1, Scalar(0, 69, 255), 2);
		}
	}
}
 
void main() {
 
	string path = "temp.png";
	Mat img = imread(path);
 
//图像的预处理
	//1.将照片转换为灰度
	cvtColor(img, imgGray, COLOR_BGR2GRAY);
	//2.高斯模糊
	GaussianBlur(imgGray, imgBlur, Size(3, 3), 3, 0);
	//3.Canny边缘检测器
	Canny(imgBlur, imgCanny, 25, 75);
	//4.创建一个可以使用膨胀的内核
	Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
	//5.图像膨胀
	dilate(imgCanny, imgDil, kernel);
 
	getContours(imgDil,img);
 
	imshow("Image", img);
 
	waitKey(0);
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/994450.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号