基于C++的OpenCV4入门基础–图像轮廓计算

不管现实多么惨不忍睹,都要持之以恒地相信,这只是黎明前短暂的黑暗而已。不要惶恐眼前的难关迈不过去,不要担心此刻的付出没有回报,别再花时间等待天降好运。真诚做人,努力做事!你想要的,岁月都会给你。基于C++的OpenCV4入门基础–图像轮廓计算,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

  1. 轮廓的特征描述
    在对实际图像进行轮廓查找时,得到的轮廓数量很多。获取轮廓后,通常基于轮廓的特征进行筛选、识别和处理。例如,基于轮廓的周长和面积对轮廓进行筛选,然后绘制筛选的目标轮廓或其最小外接矩形。

常用的轮廓特征,包括图像距、轮廓周长、轮廓近似、凸包、边界矩形、拟合图形等特征。

2 轮廓的面积、周长、质心和近似多边形
面积、周长、质心是常用的轮廓特征

2.1轮廓的面积和周长
几何矩实质是面积或质量。函数 cv.moments() 的返回值 Moments[‘m00’] 表示轮廓面积。
轮廓的面积也可以使用函数 cv2.contourArea() 计算。
轮廓的周长可以使用函数 cv2.arcLength() 计算。

//计算轮廓面积
CV_EXPORTS_W double contourArea( InputArray contour, bool oriented = false );
//计算轮廓周长
CV_EXPORTS_W double arcLength( InputArray curve, bool closed );

2.2利用轮廓的面积和周长,对轮廓进行过滤

	Mat src = imread("F:/code/images/rice.png");
	CV_Assert(!src.empty());
	namedWindow("input", WINDOW_AUTOSIZE);
	imshow("input", src);


	//高斯滤波
	GaussianBlur(src, src, Size(3, 3), 0);

	//得到灰度图
	Mat gray, binary;
	cvtColor(src, gray, COLOR_RGB2GRAY);
	imshow("gray", gray);

	//得到二值图
	threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
	imshow("binary", binary);

	
	//发现轮廓
	vector<vector<Point>>contours;//因为每个contour都是一系列点的集合
	vector<Vec4i> hierarchy;//层次信息
	findContours(binary, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());

	printf("%llu", contours.size());//25

	for (size_t t = 0; t < contours.size(); t++) {

		//图像轮廓计算:计算面积和周长
		double area = contourArea(contours[t]);
		double length = arcLength(contours[t], true);
		printf("area:%.2f, contour length:%.2f\n", area, length);
		//通过面积和周长来过滤掉一些轮廓
		if (area < 1800 || length < 10) continue;
		drawContours(src, contours, t, Scalar(0, 0, 255), 1, 8);
	}
	imshow("find contours demo", src);

3,对轮廓的其他计算
获取轮廓最大外接矩形、旋转矩形、轮廓最小外接矩形

3.1 C++ API
boundingRect()得到包覆此轮廓的最小正矩形,minAreaRect()得到包覆轮廓的最小斜矩形

CV_EXPORTS_W Rect boundingRect( InputArray array );
CV_EXPORTS_W RotatedRect minAreaRect( InputArray points );

轮廓的旋转矩形是通过minAreaRect返回的旋转矩形
轮廓的最小外接矩形利用获取旋转矩形的四个顶点,通过绘制四条直线实现绘制

//获取轮廓最大外接矩形
		Rect box = boundingRect(contours[t]);
		rectangle(src, box, Scalar(0,0,255), 1, LINE_AA);
		
		//椭圆绘制
		RotatedRect rrt = minAreaRect(contours[t]);
		ellipse(src, rrt, Scalar(255, 0, 0), 1, 8);

		//获取轮廓最小外接矩形
		Point2f pts[4];
		rrt.points(pts);
		for (int i = 0; i < 4; i++) {
			line(src, pts[i], pts[(i + 1) % 4], Scalar(0, 255, 0), 1, 8);//编程技巧 % 4
		}

在这里插入图片描述

4,轮廓逼近
4.1 轮廓逼近的本质是减少编码点
C++ API:approxPolyDP

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

curve:以顶点构成的二维向量组表示的曲线(如轮廓列表 contours 中的一个轮廓)
approxCurve:近似多边形顶点坐标 (x,y) 的二维向量组
epsilon:近似精度,浮点数,原始曲线与近似多边形之间的最大距离
closed:曲线闭合标志,True 表示近似曲线是闭合的

4.2 实例

	Mat src1 = imread("F:/code/images/contours.png");
	CV_Assert(!src1.empty());
	imshow("input1", src1);
	
	//获取轮廓
	vector<vector<Point>>contours1;
	contour_info2(src1, contours1);
	
	//多边形逼近
	for (size_t t = 0; t < contours1.size(); t++) {
		Moments mm1 = moments(contours1[t]);
		//可以获取轮廓的中心位置
		double cx = mm1.m10 / mm1.m00;
		double cy = mm1.m01 / mm1.m00;
		circle(src1, Point(cx, cy), 3, Scalar(255, 0, 0), 2, 8, 0);

		double area = contourArea(contours1[t]);
		double length = arcLength(contours1[t], true);
		
		Mat result;//放多边形的点对
		approxPolyDP(contours1[t], result, 4, true);
		printf("contour corners :%d,contour area:%.2f,contour length:%.2f\n", result.rows, area, length);

		if (result.rows == 6) {
			putText(src1, "poly", Point(cx, cy - 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 0, 255), 1, 8);
		}

		if (result.rows == 4) {
			putText(src1, "rectangle", Point(cx, cy - 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 255, 255), 1, 8);
		}

		if (result.rows == 3) {
			putText(src1, "triangle", Point(cx, cy - 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(255, 0, 255), 1, 8);
		}

		if (result.rows > 10) {
			putText(src1, "circle", Point(cx, cy - 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(255, 255, 0), 1, 8);
		}
		
		drawContours(src1, result, -1, Scalar(0,0,255), 8);
	}

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/182005.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!