opencv检测椭圆

wushouhui 2008-05-23 10:11:54
#include "stdafx.h"
#include <iostream.h>
#include "ipl.h"
#include "cv.h"
//#include "_cv.h"
//#include "vlgrfmts.h"
//-----------------------------
////////UTILITY FUNCTIONS
//
// Read in a BMP and convert it into an IPL
// fin The file name of the BMP with path
// plannar If set, convert the image to plannar
// flip If set, mirror the image around the horizontal axis, set
// IPL_ORIGIN_BL)
IplImage * readBMP2IPL(char *fin, int plannar = 0, int flip = 0)
{
int filter;
int width=0,height=0,color=55,hdr_ret=0,close_ret = 0,rd_ret = 0;
IplImage *I;
filter = gr_fmt_find_filter(fin ); //Get file type
hdr_ret = gr_fmt_read_header( filter, &width, &height, &color );//image params
I = cvCreateImageHeader( cvSize(width, height), IPL_DEPTH_8U, 3); //create image header
I->align = IPL_ALIGN_QWORD; //fix the problem that cvCreateImage uses align 4
I->depth != IPL_DEPTH_32F ? iplAllocateImage( I, 0, 0 ) :iplAllocateImageFP( I, 0, 0 );
rd_ret = gr_fmt_read_data(filter, I->imageData, I->widthStep, color); //read in the data, origin TL
close_ret = gr_fmt_close_filter( filter );
if(plannar) //If plannar order desired, turn it into plannar order
{
IplImage *Ip = iplCreateImageHeader(3, 0, IPL_DEPTH_8U, "RGB","BGR", IPL_DATA_ORDER_PLANE, I->origin, IPL_ALIGN_QWORD, width, height, NULL,NULL,NULL,NULL);
iplAllocateImage(Ip, 0,0);
iplConvert(I,Ip);
cvReleaseImage( &I );
I = Ip;
}
if(flip) //User wants IPL_ORIGIN_BL
{
iplMirror(I, I, 0); //flipporuni
I->origin = IPL_ORIGIN_BL;
}
return I;
}
//////////////////////////////////////////
// Write IPL image to disk as a BMP image (not optimized but step by step simplistic)
// fout Path\filename to write to
// I IPL image to be written
//
// Image fomat may be any of:
// dataOrder Plane or Pixel
// 1 channel (GRAY) or 3 (RGB)
// 8U, 8S, 32F
// Origin TL or BL (if BL, image is flipped to conform to TL bmps)
//
// If image is not RGB or GRAY, RGB is simply imposed on the Image. E.g. if it's YUV,
// the image will be stored as BGR with B=Y, G=U, and R=V
void writeIPL2BMP(char *fout, IplImage *I)
{
IplImage *Isav,*Itmp;
Isav = iplCloneImage(I);
//Convert to pixel order if needed
if(I->dataOrder == IPL_DATA_ORDER_PLANE)
{
Itmp = iplCreateImageHeader(I->nChannels,
I->alphaChannel, I->depth, I->colorModel,
I->channelSeq, IPL_DATA_ORDER_PIXEL, I->origin,
I->align,
I->width, I->height, NULL, NULL,NULL,NULL);
if(I->depth == IPL_DEPTH_32F)
iplAllocateImageFP(Itmp, 1,0.0);
else
iplAllocateImage(Itmp, 1,0);
iplConvert(I, Itmp);
iplDeallocate (I, IPL_IMAGE_ALL);
I = Itmp;
}
//Image is now pixel order. Convert to 8U if needed.
if(I->depth == IPL_DEPTH_8S)
I->depth = IPL_DEPTH_8U;
else if(I->depth == IPL_DEPTH_32F)
{
float min,max;
iplMinMaxFP (I, &min, &max);
Itmp = iplCreateImageHeader(I->nChannels,
I->alphaChannel, IPL_DEPTH_8U, I->colorModel,
I->channelSeq, IPL_DATA_ORDER_PIXEL, I->origin,
I->align,
I->width, I->height, NULL, NULL,NULL,NULL);
iplAllocateImage(Itmp, 1,0);
if(min >= max) max = (float)(min + 1.0);
iplScaleFP (I, Itmp, min, max);
iplDeallocate (I, IPL_IMAGE_ALL);
I = Itmp;
}
//Image is now pixel order, 8U. Convert to RGB if needed
if(I->nChannels == 3)
{
strcpy(I->colorModel,"RGB");
strcpy(I->channelSeq,"BGR");
}
else if(I->nChannels == 1)
{
Itmp = iplCreateImageHeader(3,
I->alphaChannel, IPL_DEPTH_8U, "RGB",
"BGR", IPL_DATA_ORDER_PIXEL, I->origin, I->align,
I->width, I->height, NULL, NULL,NULL,NULL);
iplAllocateImage(Itmp, 1,0);
iplGrayToColor (I, Itmp, 1.0, 1.0, 1.0);
iplDeallocate (I, IPL_IMAGE_ALL);
I = Itmp;
}
else
return;
//Image is now pixel order, 8U, RGB, flip it if the origin is BL
if(I->origin == IPL_ORIGIN_BL)
{
iplMirror(I, I, 0);
}
//FINALLY, WRITE THE IMAGE:
int write_ret = gr_fmt_write_image( I->imageData, I->widthStep,
I->width, I->height, I->colorModel[0] =='R'?1:0,fout, "bmp");
//Return image to its original state
iplDeallocate(I, IPL_IMAGE_ALL);
I = Isav;
}
//-----------------------------
void main()
{
IplImage * input_img=NULL;
int plannar=0;
int flip=0;
char fin[]="circles.bmp";
char fout[]="result.bmp";


//作一些声明
CvMemStorage *storage;
int header_size, i, count,length, width;
CvSeq *contour;
CvBox2D * myBox; //用于画圆和椭圆
CvPoint *PointArray;
CvPoint2D32f *PointArray32f;
CvPoint myCenter;

// 分配内存
myBox= (CvBox2D *) malloc(sizeof(CvBox2D));
header_size = sizeof(CvContour);
storage = cvCreateMemStorage (1000); // For FindContours.

// 读入图象input_img并转换为IPLIMAGE格式
//已经定义 char fin[]="circles.bmp";
input_img=readBMP2IPL(fin,plannar, flip);
cout<<" The following is the attribute for current image:\n";
cout<<"Num of channels: "<< input_img->nChannels<<endl;
cout<<"depth: "<<input_img->depth<<endl; // pixel depth in bits
cout<<"Color mode: "<<input_img->colorModel<<endl;
cout<<"Channel Seq: "<<input_img->channelSeq<<endl;
cout<<"DataOrder: "<<input_img->dataOrder<<endl;
cout<<"Origin (top-left /bottom left): "<<input_img->origin<<endl;
cout<<"Width : "<<input_img->width<<endl;
cout<<"Height : "<<input_img->height<<endl;
//

//得到图象INPUT-IMAGE的宽、高

int w = input_img->width;
int h = input_img->height;
//创建临时图象,m_tmp8uC1用于"CANNY",m_tmp8uC3用于预处理

//这个m_tmp8uC1用于CANNY - 1 CHANNEL (灰度)
//与输入的input_img大小一样
IplImage* m_tmp8uC1= cvCreateImage(
cvSize(w ,h ),
IPL_DEPTH_8U,1); //灰度图象

//这个用于预处理- 3 CHANNEL (彩色)
//大小同输入的input_img
IplImage* m_tmp8uC3= cvCreateImage(
cvSize( w ,h),
IPL_DEPTH_8U,3); //彩色图象


//预处理
//这里使用简单的BLUR来去除噪声,使用简单的邻域平均方法进行线性滤波
iplBlur(input_img,m_tmp8uC3, 2,2,1,1);

//将结果转换为灰度图象m_tmp8uC1
iplColorToGray(m_tmp8uC3, m_tmp8uC1);

//释放临时的彩色图象m_tmp8uC3
cvReleaseImage(&m_tmp8uC3);
// 第一个关键方程
// CANNY边缘检测,结果是黑白图象,其中白色表示轮廓
//第二个关键方程,该方程分离出所有轮廓。查看文档说明
int number_of_c=cvFindContours (m_tmp8uC1 , storage, &contour,
header_size, CV_RETR_EXTERNAL,
CV_CHAIN_APPROX_SIMPLE);
cout<<"number: "<<number_of_c<<endl;
// 检查所有的轮廓
while(contour!=NULL) //当轮廓contour不为空时
{
if(CV_IS_SEQ_CURVE(contour))
//#define CV_IS_SEQ_CURVE( seq ) \
//(CV_GET_SEQ_KIND(seq) == CV_SEQ_KIND_CURVE)
//表示当contour是CV_SEQ_KIND_CURVE型的
{
// HOW MANY POITS HAS THE CONTOUR ??
count = contour ->total;//序列元素的总数,即轮廓上点的总数
//分配内存
PointArray = (CvPoint *)malloc(count * sizeof(CvPoint));
//COPY THE POINTS TO A ARRAY
//将序列拷入一个连续的缓存中
cvCvtSeqToArray(contour, PointArray, CV_WHOLE_SEQ);
// ALLOC MEM
PointArray32f = (CvPoint2D32f *)
malloc((count + 1) * sizeof(CvPoint2D32f));
//CONVERT THE ARRAY TO A 2ND (32FLOAT)
// 这个用于cvFitELLIPSE

for (i=0; i<count-1; i++)
{
PointArray32f[i].x = (float)(PointArray[i].x);
PointArray32f[i].y = (float)(PointArray[i].y);
}
PointArray32f[i].x = (float)(PointArray[0].x);
PointArray32f[i].y = (float)(PointArray[0].y);
//FOR DEBUGGING YOU CAN DRAW THE CONTOUR
cvDrawContours(input_img,contour,RGB(0,0,255),RGB(0,255,0),1,1);
//函数cvFITELLIPSE 最少需要6个点,从而拟合出目标的轮廓
// IS IT ?
if (count>=7)
{
//FIND THE BEST FITTING ELLIPSE IN THIS CONTOUR
//找出在这个轮廓中最适合的椭圆
cvFitEllipse(PointArray32f, count,myBox);
//从"myBox"中提出结果
//CENTER
//中心
myCenter.x = (int) myBox->center.x;
myCenter.y = (int) myBox->center.y;
//HEIGHT AND WITH (THE 2 AXES OF THE ELLIPSE)
length =(int)myBox->size.height;
width = (int)myBox->size.width;
//AND THE ANGLE
float myAngle= myBox->angle;
// 检查这个椭圆是否在图象内
if ((myCenter.x > 0) && (myCenter.y >0))
{
//画圆
cvCircle(input_img,myCenter,(int)length/2 ,RGB(255,0,0),1);
//画椭圆
cvEllipse(input_img,
myCenter,
cvSize ((int)width/2,(int)length/2) ,
myBox->angle,
0,360,RGB(255,0,255),1);
}
}
free(PointArray32f );
free(PointArray );
}
// GOT TO THE NEXT CONTOUR (IF ANY)
//取下一个轮廓
contour = contour->h_next;
}
free (contour);
free (myBox);
cvReleaseImage(&m_tmp8uC1);
cvReleaseMemStorage(&storage);
writeIPL2BMP(fout,input_img);//已定义 char fout[]="result.bmp";
}运行以后总是有头文件识别不了,大家帮看看
...全文
2763 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
brk1985 2009-06-06
  • 打赏
  • 举报
回复
是缺少很多文件,我也刚下了这个程序。
添加了"stdafx.h"后,发现无gr_fmt_find_filter函数等
wushouhui 2008-05-26
  • 打赏
  • 举报
回复
错误就是#include "stdafx.h" 不识别,删除以后就是ipl.h不识别
xkyx_cn 2008-05-23
  • 打赏
  • 举报
回复
哪些 头文件,
最好把编译得到的错误也发出来,代码太多,看得有点晕
请把代码放入[ code=C/C++][/code ] 中间

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧