您的位置:首页 > 运维架构

Opencv椭圆拟合

2015-12-17 14:13 447 查看
一 轮廓检测

二 椭圆拟合

三 程序操作

一 轮廓检测

在进行椭圆拟合时需要先检测出轮廓中的点,这就需要用到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);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opencv