Opencv椭圆拟合

转:https://blog.csdn.net/longwoshixiao/article/details/50341015 

一 轮廓检测
二 椭圆拟合
三 程序操作
一 轮廓检测
在进行椭圆拟合时需要先检测出轮廓中的点,这就需要用到cvFindContous命令。

cvFindContours(
CvArr* image, 
CvSeq** first_contour,
int header_size CV_DEFAULT(sizeof(CvContour)),
int mode CV_DEFAULT(CV_RETR_LIST),
int method CV_DEFAULT(CV_CHAIN_APPROX_SIMPLE),
CvPoint offset CV_DEFAULT(cvPoint(0,0)))
image: 是一个二值图像,一般由cvThreShold得到 
storage: 返回轮廓的容器 
first_contour: 输出函数, 指向第一个轮廓的地址 
header_size: 序列的尺寸,如果method=CV_CHAIN_CODE, 则 
header_size=sizeof(CvChain),否则为sizeof(CvContour) 
mode: CV_RETR_EXTERNAL, 只检索最外轮廓 
CV_RETR_LIST, 采用横向列表方式检索所用的轮廓 
method: CV_CHAIN_CODE - Freeman 链码的输出轮廓. 其它方法输出多边形(定点序列). 
CV_CHAIN_APPROX_NONE - 将所有点由链码形式翻译(转化)为点序列形式 
CV_CHAIN_APPROX_SIMPLE - 压缩水平、垂直和对角分割,即函数只保留末端的象素点 
CV_CHAIN_APPROX_TC89_L1 
CV_CHAIN_APPROX_TC89_KCOS - 应用 Teh-Chin 链逼近算法. CV_LINK_RUNS - 通过连接为 1 的水平碎片使用完全不同的轮廓提取算法。仅有 CV_RETR_LIST 提取模式可以在本方法中应用 
offset: 偏移量,用于移动所有轮廓点

二 椭圆拟合
cvFitEllipse( 
const CvPoint2D32f* points, 
int count, 
CvBox2D* box )
三 程序操作

CvMemStorage*stor; 
CvSeq*cont; 
CvFont font; 
CvBox2D32f*box; 
CvPoint*PointArray; 
CvPoint2D32f*PointArray2D32f; 
double minarea=10,maxarea=500; 
stor=cvCreateMemStorage(0); 
cont=cvCreateSeq(CV_SEQ_ELTYPE_POINT,sizeof(CvSeq),sizeof(CvPoint),stor); 
cvThreshold(image03,image02,slider_pos,255,CV_THRESH_BINARY); 
cvFindContours(image02,stor,&cont,sizeof(CvContour), 
CV_RETR_LIST,CV_CHAIN_APPROX_NONE,cvPoint(0,0)); 
for(;cont;cont=cont->h_next) 

int i; 
int count=cont->total;//轮廓个数 
CvPoint center; 
CvSize size; 
/*个数必须大于6,这是cvFitEllipse_32f的要求*/ 
if(count<6) 

continue; 

double a=abs(cvContourArea(cont)); 
cvInitFont(&font,CV_FONT_HERSHEY_COMPLEX,0.5f,0.5f,0,1,8); //初始化字体 
if (a>=minarea&&a<=maxarea) 

//分配内存给点集 
PointArray=(CvPoint*)malloc(count*sizeof(CvPoint)); 
PointArray2D32f= (CvPoint2D32f*)malloc(count*sizeof(CvPoint2D32f)); 
//分配内存给椭圆数据 
box=(CvBox2D32f*)malloc(sizeof(CvBox2D32f)); 
//得到点集 
cvCvtSeqToArray(cont,PointArray,CV_WHOLE_SEQ); 
//将CvPoint点集转化为CvBox2D32f集合 
for(i=0;i<count;i++) 

PointArray2D32f[i].x=(float)PointArray[i].x; 
PointArray2D32f[i].y=(float)PointArray[i].y; 

//拟合当前轮廓 
cvFitEllipse(PointArray2D32f,count,box); 
//绘制当前轮廓 cvDrawContours(image04,cont,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; 
centerfile<<box->center.x<<" "<<box->center.y<<endl; 
//画椭圆 
cvEllipse(image04,center,size,box- >angle,0,360,CV_RGB(0,0,255),1,CV_AA,0); 
free(PointArray); 
free(PointArray2D32f); 
free(box); 

展开阅读全文

没有更多推荐了,返回首页