www.pudn.com > circleDetection.rar > circledetection.cpp
// readbmp.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include#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< depth< colorModel< channelSeq< dataOrder< origin< width< height< 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: "< 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 =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"; }