opencv c++ 轮廓逼近与拟合

1、概念

        轮廓逼近:指用越来越多的多边形对轮廓进行拟合,从而获得与轮廓近似的多边形,并获取多边形的形状。目的是为了减少编码点(人话:减少数据量)

        拟合:生成最相似的圆或多边形。

2、代码

        API:


void cv::approxPolyDP	(	InputArray 	curve,
                            OutputArray 	approxCurve,
                            double 	epsilon,
                            bool 	closed 
                            )	

epsilon——逼近精度,一般选4.

closed ——是否选用封闭轮廓

RotatedRect cv::fitEllipse	(	InputArray 	points	)	

 只能获取到多边形的边数,可以使用result.rows调用出边数。

获取拟合多边形的边数:

void QuickDemo::contour_neighbor(Mat& image)
{
	GaussianBlur(image, image, Size(3,3),0);
	Mat gray;
	cvtColor(image, gray, COLOR_BGR2GRAY);
	Mat binary;
	threshold(gray, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
	namedWindow("THRESH_OTSU", WINDOW_FREERATIO);
	imshow("THRESH_OTSU", binary);

	vector<vector<Point>> contours;
	vector<Vec4i> hierachy;
	findContours(binary, contours, hierachy, RETR_EXTERNAL,CHAIN_APPROX_SIMPLE,Point());
	cout << contours.size() << endl;
	RNG rng(12345);
	string word = "some::";
	//多边形逼近
	for (size_t t = 0; t < contours.size(); ++t) {
		Mat result;
		approxPolyDP(contours[t], result, 4, true);
		cout << result.rows << "," << result.cols << endl;
		//利用几何矩找到轮廓中心位置

		Moments mm = moments(contours[t]);
		double cx = mm.m10 / mm.m00;
		double cy = mm.m01 / mm.m00;
		circle(image, Point(cx, cy), 3, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3, 8);
		putText(image, word + (char)rng.uniform(65,90)+ (char)rng.uniform(65, 90), Point(cx-100, cy - 100), FONT_HERSHEY_PLAIN, 3, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 2, 8);
		double area = contourArea(contours[t]);//面积
		double clen = arcLength(contours[t],false);//周长
		drawContours(image, contours, t, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3, 8);
	}
	namedWindow("image", WINDOW_FREERATIO);
	imshow("image", image);
}

 拟合圆、椭圆:

void QuickDemo::image_fit(Mat& image)
{
	GaussianBlur(image, image, Size(3, 3), 0);
	Mat gray;
	cvtColor(image, gray, COLOR_BGR2GRAY);
	Mat binary;
	threshold(gray, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
	namedWindow("THRESH_OTSU", WINDOW_FREERATIO);
	imshow("THRESH_OTSU", binary);

	vector<vector<Point>> contours;
	vector<Vec4i> hierachy;
	findContours(binary, contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
	cout << contours.size() << endl;

	RNG rng(12345);
	string word = "some::";

	//拟合圆/椭圆
	for (size_t t = 0; t < contours.size(); ++t) {
		drawContours(image, contours, t, Scalar(rng.uniform(0, 255), rng.uniform(0, 255)), 3, 8);
		RotatedRect rrt = fitEllipse(contours[t]);
		float w = rrt.size.width;
		float h = rrt.size.height;
		Point center = rrt.center;
		circle(image, center, 10, Scalar(rng.uniform(0, 255), rng.uniform(0, 255)), 3, 8);
		ellipse(image, rrt, Scalar(rng.uniform(0, 255), rng.uniform(0, 255)), 2, 8);
	}
	namedWindow("fit result", WINDOW_FREERATIO);
	imshow("fit result", image);
}

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值