opencv入门(16)--绘制轮廓包围框

16.1 引言

在寻找到目标轮廓后,很多轮廓基本是不规则的,为了便于目标定位可以用规则的形状将轮廓框选起来。如矩形、椭圆等。

16.2 相关API

16.2.1  approxPolyDP多边拟合函数

该算子使用 Douglas-Peucker 算法求得一条顶点较少的多折线/多边形,以指定的精度近似输入的曲线或多边形。

Douglas-Peucker(拉默-道格拉斯-普克ROP) 算法原理:

  1. 在曲线首尾两点间虚连一条直线,求其余点到该直线的距离。
  2. 设定距离阈值,最大距离大于阈值,则保留该点。否则将其余点都去除。
  3. 依据保留的点将直线分为两段,重复进行1,2步骤,迭代操作,直至无点可舍。

如下图所示:

·void approxPolyOP( InputArray curve, OutputArray approxCurve, double epsilon, bool closed)

参数含义
作用多边拟合,减少多边形轮廓点集
输入curve

一般由图像的轮廓点组成的点集

approxCurve输出的多边形点集
epsilon输出的精度,表示原始曲线与近似之间的最大距离
closed

多边形是否封闭,true:封闭,false:不封闭

返回值void

16.2.2 点集的矩形包围框

·Rect boundingRect( InputArray points)

参数含义
作用得到轮廓周围最小矩形左上交点坐标和右下交点坐标,绘制一个矩形
输入points

单个轮廓的点集

返回值Rect矩形

·RotatedRect minAreaRect( InputArray points)

参数含义
作用得到轮廓的最小包围矩形
输入points

单个轮廓的点集

返回值RotatedRect旋转的矩形

16.2.3 点集的圆形包围框

·viod minEnclosingCircle( InputArray points,Pointsf& center, float &radius)

参数含义
作用获取最小包围圆形
输入points单个轮廓的点集
center输出的圆心位置

radius

输出的圆半径
返回值void

16.2.4 点集的椭圆形包围框

·RotateRect fitEllipse( InputArray points)

参数含义
作用得到轮廓的最小包围椭圆形
输入points

单个轮廓的点集

返回值RotatedRect椭圆形

16.3 代码示例

Mat src, cannyImg,dst;
const char* OUTPUTWIN = "outputImg";
int thresholdValue = 100;
int thresholdMax = 255;
RNG rng(12345);
void CannyFindContours(int, void*)
{
	Mat brinaryImg;
	//canny边缘检测,(此外可以使用阈值分割等)
	Canny(cannyImg, brinaryImg, thresholdValue, thresholdValue * 2,3,false);
	vector<vector<Point>> contours;
	vector<Vec4i> hierachy;
	//对边缘检测后的图像进行轮廓寻找
	findContours(brinaryImg, contours, hierachy, RETR_TREE, CHAIN_APPROX_NONE,Point(0,0));


	//多边拟合
	vector<vector<Point>> approxCotours(contours.size());
	vector<Rect> RectVec(contours.size());
	vector<RotatedRect> RotatedRectVec(contours.size());
	vector<Point2f> centerVec(contours.size());
	vector<float> radiusVec(contours.size());
	vector<RotatedRect> ellipseVec(contours.size());
	for (int i = 0; i < contours.size(); i++)
	{
		approxPolyDP(contours[i], approxCotours[i],5,true);
		//矩形
		RectVec[i]=boundingRect(approxCotours[i]);
		//圆形
		minEnclosingCircle(approxCotours[i], centerVec[i], radiusVec[i]);

		if (approxCotours[i].size() > 5)
		{
			//最小旋转矩形
			RotatedRectVec[i] = minAreaRect(approxCotours[i]);
			//椭圆形
			ellipseVec[i] = fitEllipse(approxCotours[i]);
		}
	}

	Point2f ptemp[4];
	for (int i = 0; i < contours.size(); i++)
	{
		Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
		//绘制矩形
		rectangle(src, RectVec[i], color, 2, 8);
		//绘制圆形
		circle(src,centerVec[i],radiusVec[i],color,2,8);

		if (approxCotours[i].size() > 5)
		{
			//绘制椭圆
			ellipse(src, ellipseVec[i], color, 2, 8);
			//绘制旋转矩形
			RotatedRectVec[i].points(ptemp);
			for (int n = 0; n < 4; n++)
			{
				line(src, ptemp[n], ptemp[(n + 1) % 4], color, 2, 8);
			}

		}

	}

	imshow(OUTPUTWIN, src);
}


int main(int argc, char** argv)
{
	//源图像
	src = imread("D:\\testimg\\CSet12\\yingbi.png");
	if (src.empty())
	{
		printf("Could not load the image...\n");
		return -1;
	}
	else;

	namedWindow("inputImg", WINDOW_AUTOSIZE);
	imshow("inputImg", src);
	namedWindow(OUTPUTWIN, WINDOW_AUTOSIZE);

	cvtColor(src, cannyImg,COLOR_BGR2GRAY);

	const char* trackbarTitle = "threshold";
	createTrackbar(trackbarTitle, OUTPUTWIN, &thresholdValue, thresholdMax, CannyFindContours);
	CannyFindContours(0, 0);


	waitKey(0);
	return 0;
}

16.4 判断点与多边形的关系

多边形测试简单来说,就是测试一个点是否在给定的多边形内部、边缘或外部的方法。

16.4.1 相关API

·double pointPolygonTest( InputArray contour, Point2f pt,bool measureDist)

参数含义
作用计算点和多边形的关系
输入contour

多边形轮廓

pt测试点
measureDist是否返回距离值;false:1表示在内部,0表示在边界上,-1表示在外部;true返回实际距离。
返回值double

跟参数3相关

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值