轮廓近似

当我们查找到一个轮廓进行形状分析时,通常需要使用多边形来逼近一个轮廓,使得顶点数变少,OpenCV的approxPolyDP函数就可以实现这个功能。

approxPolyDP函数使用了Douglas-Peucker算法:

1、先从轮廓中找出两个最远的点,将两点相连,即b-c;

2、在原来的轮廓上查找一个离线段距离最远的点,将该点加入逼近后的新轮廓中,即c-d;

3、然后重复前面的算法,不断迭代,将最远的点添加进来,直到所有的点到多边形的最短距离小于指定的精度。

函数原型 

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

参数解析:

  • curve:存储在std :: vector或Mat中的2D点的输入向量,一般是轮廓点的集合。
  • approxCurve:输出拟合的多边形点集, 类型应与输入曲线的类型相同。
  • epsilon:指定近似精度的参数, 这是原始曲线和它的近似之间最大距离。
  • closed:如果为true,则闭合近似曲线(其第一个和最后一个顶点为连接的);否则,不闭合。

关键代码

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
 
//定义颜色常量
const cv::Scalar RED = cv::Scalar(0, 0, 255);					//红色
const cv::Scalar PINK = cv::Scalar(230, 130, 255);				//粉色
const cv::Scalar BLUE = cv::Scalar(255, 0, 0);					//蓝色
const cv::Scalar LIGHTBLUE = cv::Scalar(255, 255, 160);			//亮蓝色
const cv::Scalar GREEN = cv::Scalar(0, 255, 0);					//绿色
const cv::Scalar YELLOW = cv::Scalar(175, 255, 255);			//黄色
const cv::Scalar DEEP_SKYBLUE = cv::Scalar(0, 191, 255);		//深天空蓝
const cv::Scalar ORCHID = cv::Scalar(218, 112, 214);			//兰花
const cv::Scalar WHITE = cv::Scalar(255, 255, 255);				//白色
 
int main()
{
	Mat srcImage, grayImage, binaryImage;
	srcImage = imread("OpenCV.jpg",1);
	resize(srcImage, srcImage,Size(srcImage.cols/2,srcImage.rows/2));
	
	Mat dstImage_3(srcImage.size(), CV_8UC3, Scalar::all(0));
	Mat dstImage_5(srcImage.size(), CV_8UC3, Scalar::all(0));
	Mat dstImage_8(srcImage.size(), CV_8UC3, Scalar::all(0));
	
	cvtColor(srcImage, grayImage,COLOR_RGB2GRAY);
	imshow("grayImage", grayImage);
	
	threshold(grayImage, binaryImage,200,255, THRESH_BINARY_INV);
	imshow("binaryImage", binaryImage);
	
	vector<vector<Point>> contours;
	findContours(binaryImage, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE, cv::Point(0, 0));
	
	vector<vector<Point>> contours_ploy(contours.size());
	for (int i=0;i<contours.size();i++)
	{
		drawContours(srcImage, contours, i, Scalar(230, 130, 255), 1, CV_AA);
		//epsilon==3
		approxPolyDP(Mat(contours[i]), contours_ploy[i], 3, true);
		drawContours(dstImage_3, contours_ploy, i, PINK, 1, CV_AA);
		//epsilon==5
		approxPolyDP(Mat(contours[i]), contours_ploy[i], 5, true);
		drawContours(dstImage_5, contours_ploy, i, LIGHTBLUE, 1, CV_AA);
		//epsilon==8
		approxPolyDP(Mat(contours[i]), contours_ploy[i], 8, true);
		drawContours(dstImage_8, contours_ploy, i, YELLOW, 1, CV_AA);
	}
	
	imshow("srcImage", srcImage);
	imshow("dstImage_3", dstImage_3);
	imshow("dstImage_5", dstImage_5);
	imshow("dstImage_8", dstImage_8);
	
	waitKey(0);
	
	destroyAllWindows();
	
	return 0;
}

从以上结果可以看出,设置的精度越小,多边形越拟合。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值