我是靠谱客的博主 暴躁红酒,最近开发中收集的这篇文章主要介绍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);
}

最后

以上就是暴躁红酒为你收集整理的opencv c++ 轮廓逼近与拟合的全部内容,希望文章能够帮你解决opencv c++ 轮廓逼近与拟合所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部