opencv例程之椭圆拟合

所用库函数如下:

//拷贝序列中的元素到一个连续的内存块中 

void* cvCvtSeqToArray( const CvSeq* seq, void* elements, CvSlice slice=CV_WHOLE_SEQ );

//对给定的一组二维点集作椭圆的最佳拟合(最小二乘意义上的)

回的结构与 cvEllipse 中的意义类似,除了 size 表示椭圆轴的整个长度,而不是一半长度。

 void cvFitEllipse( const CvPoint2D32f* points, int count, CvBox2D* box )

绘制时候box的angle要翻转下

精简的拟合代码如下:

#include<cv.h>
#include<highgui.h>
#include<stdio.h>
#include<malloc.h>
#pragma comment(lib,"cv.lib")
#pragma comment(lib,"cxcore.lib")
#pragma comment(lib,"highgui.lib")
#pragma comment(lib,"cvaux.lib")
/********************************************************************************
*
*
*  本程序是精简的最小二乘意义上的椭圆拟合
*  作者:xlh145
*  博客:http://blog.csdn.net/xlh145/
*
*
********************************************************************************/
IplImage * image = NULL;//源图像
IplImage * dst =NULL;//用于输出结果的目标单通道图像
const char* windowname = "椭圆拟合demo";
const char* windowresult = "拟合结果";
int threshold = 70;//阈值
CvPoint *PointArray;//数组点
CvPoint2D32f *PointArray32f;//供椭圆拟合的数组点
CvBox2D* box;//拟合后的存储盒子
void OnTrack(int pos) 
{
	CvPoint center;//拟合后的椭圆的中心点
	CvSize  size;//绘制椭圆需要的参数
	CvMemStorage* storage=cvCreateMemStorage(0);//存储空间
	CvSeq* seq=cvCreateSeq(CV_SEQ_POINT_SET,sizeof(CvSeq),sizeof(CvPoint),storage);//储存轮廓序列

	IplImage * temp = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,1); //创建临时图像
	cvThreshold(image,temp,threshold,255,CV_THRESH_BINARY);//阈值化
	//查找边缘
	cvFindContours(temp,storage,&seq,sizeof(CvContour),CV_RETR_CCOMP,CV_CHAIN_APPROX_NONE,cvPoint(0,0));
	
	cvZero(dst); //清空输出图像	
	for(;seq;seq=seq->h_next)
	{
		int count = seq->total;//外轮廓的点数
		if(count<6)  //椭圆拟合必须大于6个点
			continue;
		PointArray=	(CvPoint*)malloc(count*sizeof(CvPoint)); //创建点集的存储空间
		PointArray32f = (CvPoint2D32f*)malloc(count*sizeof(CvPoint2D32f)); //创建32f点集的存储空间
		box = (CvBox2D*)malloc(sizeof(CvBox2D)); //创建盒子的存储空间

		cvCvtSeqToArray(seq,PointArray);//将轮廓点储存到数组中
		//将点的存储类型转换为32f
		for(int i=0;i<count;i++)
		{
			PointArray32f[i].x = (float)PointArray[i].x	;
			PointArray32f[i].y = (float)PointArray[i].y	;
		}
		//开始拟合
		cvFitEllipse(PointArray32f,count,box);
		//在输出图像上绘制轮廓
		cvDrawContours(dst,seq,CV_RGB(255,255,255),CV_RGB(255,255,255),0,1,8,cvPoint(0,0));//绘制轮廓
	
 
		center.x = cvRound(box->center.x);
		center.y = cvRound(box->center.y);	
		size.width = cvRound(box->size.width*0.5); 
		size.height = cvRound(box->size.height*0.5);
		box->angle = -box->angle;//关于Y翻转
		//绘制拟合的椭圆
		cvEllipse(dst,center,size,box->angle,0,360,CV_RGB(255,0,0));
		//释放存储空间
		free(PointArray);
		free(PointArray32f);
		free(box);

	}
		cvShowImage(windowresult,dst);
}

int main()
{
	image = cvLoadImage("stuff.jpg",0);//加载目标函数
	dst = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,3); //创建目标显示的图像
	cvNamedWindow(windowname,1);//创建窗口
	cvNamedWindow(windowresult,1);//创建窗口
	cvCreateTrackbar("阈值",windowname,&threshold,255,OnTrack);
	OnTrack(70);
	while(true)
	{
		cvShowImage(windowname,image);
		if(cvWaitKey(0)>=0) break;

	}
	cvReleaseImage(&image);
	cvReleaseImage(&dst);
	cvDestroyWindow(windowname);
	cvDestroyWindow(windowresult);
	return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值