#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<<"\t"<<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); // 返回阈值
}