#include "stdafx.h" // FitCircle.cpp : 定义控制台应用程序的入口 #include "cv.h" #include "highgui.h" #include "cxcore.h" #include "cvaux.h" #include <iostream> using namespace cv; using namespace std; void main() { int BasicGlobalThreshold(int*pg,int start,int end); CvBox2D findRectContours(IplImage *src); IplImage* imgGrey=cvLoadImage("5_000004.bmp",0); //IplImage* imgGrey=cvLoadImage("28027.jpg",0); cvNamedWindow("原始图像"); //cvShowImage("fa",imgGrey); cvShowImage("原始图像",imgGrey); double t=(double)getTickCount(); IplImage* imgBasicGlobalThreshold = cvCreateImage(cvGetSize(imgGrey),IPL_DEPTH_8U,1); cvCopyImage(imgGrey,imgBasicGlobalThreshold); int pg[256],i,thre; for (i=0;i<256;i++) pg[i]=0; for (i=0;i<imgBasicGlobalThreshold->imageSize;i++) // 直方图统计 pg[(BYTE)imgBasicGlobalThreshold->imageData[i]]++; thre = BasicGlobalThreshold(pg,0,256); // 确定阈值 cout<<"The Threshold of this Image in BasicGlobalThreshold is:"<<thre<<endl;//输出显示阀值 cvThreshold(imgBasicGlobalThreshold,imgBasicGlobalThreshold,thre,255,CV_THRESH_BINARY); // 二值化 cvNamedWindow("二值图像"); cvShowImage("二值图像",imgBasicGlobalThreshold); CvBox2D box=findRectContours(imgBasicGlobalThreshold); t=((double)getTickCount()-t)/getTickFrequency(); cout<<t<<" mark点坐标"<<box.center.x<<" "<<box.center.y<<endl<<"半径"<<box.size.width<<endl; cvWaitKey(0); } CvBox2D findRectContours(IplImage *src) { CvBox2D box1; IplImage* des=cvCreateImage(cvGetSize(src),src->depth,src->nChannels); cvZero(des); CvMemStorage* memory=cvCreateMemStorage(0); CvSeq* Icontour=NULL; CvSeq* maxContour =NULL; cvShowImage("原始图像1",src); cvFindContours(src,memory,&Icontour, sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0)); double area=0; double maxArea=0; while(Icontour) { area=fabs(cvContourArea(Icontour,CV_WHOLE_SEQ)); //cout<<area<<endl; //cvDrawContours(src, Icontour, // CV_RGB(255,255,255), CV_RGB(255, 255,255), // 0, 1, 8, cvPoint(0,0)); // if(area>500 && area<20000) { goto l1; } else goto l2; l1: CvBox2D box0=cvFitEllipse2(Icontour); float a=(float)box0.size.height/(float)box0.size.width; //cout<<area<<endl; if(fabs(a)<=1.5) { cvDrawContours(des, Icontour, CV_RGB(255,255,255), CV_RGB(255, 255,255), 0, 1, 8, cvPoint(0,0)); box1=box0; cvDrawCircle(des,cvPoint(box0.center.x,box0.center.y),1,cvScalar(255,255,255),2,8,0); //cvDrawContours(des,maxContour,cvScalar(0,0,255),cvScalar(0,0,255),1,1,0,cvPoint(0,0)); } // maxContour = Icontour; l2: Icontour =Icontour->h_next; } cvShowImage("fds",des); return box1; } /*============================================================================ = 代码内容:基本全局阈值法 迭代法 ==============================================================================*/ int BasicGlobalThreshold(int*pg,int start,int end) { // 基本全局阈值法 int i,t,t1,t2,k1,k2; double u,u1,u2; t=0; u=0; for (i=start;i<end;i++) { t+=pg[i]; u+=i*pg[i]; } k2=(int) (u/t); // 计算此范围灰度的平均值 do { k1=k2; t1=0; u1=0; for (i=start;i<=k1;i++) { // 计算低灰度组的累加和 t1+=pg[i]; u1+=i*pg[i]; } t2=t-t1; u2=u-u1; if (t1) u1=u1/t1; // 计算低灰度组的平均值 else u1=0; if (t2) u2=u2/t2; // 计算高灰度组的平均值 else u2=0; k2=(int) ((u1+u2)/2); // 得到新的阈值估计值 } while(k1!=k2); // 数据未稳定,继续 //cout<<"The Threshold of this Image in BasicGlobalThreshold is:"<<k1<<endl; return(k1); // 返回阈值 }