opencv cookbook中关于轮廓提取以及表示的例子

#include "cv.h"
#include "highgui.h"
#include "iostream"
#include "windows.h"

using namespace std;
using namespace cv;

int main()
{	
	Mat image;

	image = cv::imread("2.bmp",0);

	//每条轮廓都是一个vector<Point>;所有轮廓存储在vector<vector<Point>>中
	std::vector<std::vector<cv::Point>> contours;	

	cv::findContours(image,contours,
					
					CV_RETR_EXTERNAL,			//检索外轮廓(忽略孔)
		
					CV_CHAIN_APPROX_NONE);

	// Eliminate too short or too long contours
	int cmin = 100; // minimum contour length

	int cmax = 1000; //maximum contour length

	//创建迭代器,搜索满足条件的(轮廓长度在100到1000之间的轮廓)
	std::vector<std::vector<cv::Point>>::
				
					const_iterator itc = contours.begin();

	while (itc!=contours.end())
	{
		if (itc->size()<cmin||itc->size()>cmax)
		{
			//不满足条件的轮廓,用erase函数清除
			itc = contours.erase(itc);
		}
		else
			++itc;
	}
	
	//创建显示结果的图像,type为 8位无符号整形。
	Mat resultimage(image.size(),CV_8U,cv::Scalar(255));

	//testing the bouding box 
	//创建矩形边框的轮廓约束
	cv::Rect r0 = cv::boundingRect(cv::Mat(contours[0]));
	//绘制边框
	cv::rectangle(resultimage,r0,cv::Scalar(0),2);

	//testing the enclosing circle
	//创建圆形边框的轮廓约束
	float radius; //半径

	cv::Point2f center;	//圆心

	cv::minEnclosingCircle(cv::Mat(contours[1]),center,radius);
	//绘制轮廓半径
	cv::circle(resultimage,cv::Point(center),
					
					static_cast<int>(radius),cv::Scalar(0),2);

	//testing the approximate polygon
	//用非凸多边形约束轮廓边界
	
	std::vector<cv::Point>poly;		//创建ploy轮廓点向量容器

	cv::approxPolyDP(cv::Mat(contours[3]),poly,5,true);		//多边形逼近

	//Iterate over each segment and draw it
	//迭代器方法将ploy容器中保存的点集用line连起来
	std::vector<cv::Point>::const_iterator itp =poly.begin();

	while (itp!=(poly.end()-1))
	{
		cv::line(resultimage,*itp,*(itp+1),cv::Scalar(0),2);
		++itp;
	}
	//last point linked to first point
	//使轮廓首位相接
	cv::line(resultimage,*(poly.begin()),*(poly.end()-1),cv::Scalar(20),2);

	//testing the convex hull
	//用凸多边形约束轮廓
	std::vector<cv::Point> hull;   //创建hull轮廓向量容器,存储点集

	cv::convexHull(cv::Mat(contours[2]),hull);	//凸多边形逼近

	//Iterate over each segment and draw it 
	//用与非凸多边形约束绘制方法相同的方法绘制凸多边形边界,
	//迭代器方法将hull容器中保存的点集用line函数链接起来
	std::vector<cv::Point>::const_iterator ith =hull.begin();

	while (ith!=(hull.end()-1))
	{
		cv::line(resultimage,*ith,*(ith+1),cv::Scalar(0),2);
		++ith;
	}
	//last point linked to first point
	//边界首位相接
	cv::line(resultimage,*(hull.begin()),*(hull.end()-1),cv::Scalar(20),2);

	//testing the moments计算轮廓的矩,中心位置
	//iterate over all contours
	itc = contours.begin();

	while(itc!=contours.end())
	{
		//compute all moments
		cv::Moments mom = cv::moments(cv::Mat(*itc++));
		
		//draw mass center
		cv::circle(resultimage,
				
				//position of mass center converted to integer
				cv::Point(mom.m10/mom.m00,mom.m01/mom.m00),
				
				2,cv::Scalar(0),2);
	}

	cv::drawContours(resultimage,contours,
						
					-1,cv::Scalar(0),1);

	cv::namedWindow("imagecontour");cv::imshow("imagecontour",resultimage);

	cv::waitKey(0);

}
关于书里面在用凸多边形逼近轮廓的部分,只完成了逼近的工作,将凸的多边形点集存储到hull向量容器中,但并没有做绘制的工作。其实绘制的方法与用approxPolyDP一般多边形逼近后绘制的方法相同,创建一个hull容器下的迭代器,用line函数连接相邻两点,最后令轮廓的首位像素相接即可
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值