#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
#include "cvaux.h"
#include <iostream>
#include"Timer.h"
using namespace std;
int otsu2 (IplImage *image);
CvBox2D findRectContours(const IplImage *gray);
void main()
{
IplImage* img =cvLoadImage("mark1.jpg",0);
// cvCopyImage(srcImgGrey,img0tsu);
MyTimer mt;
mt.Reset();
mt.Start();
//Sleep(1000);
int thre2;
thre2 = otsu2(img);
//cout<<"The Threshold of this Image in Otsu is:"<<thre2<<endl;//输出显示阀值
cvThreshold(img,img,thre2,255,CV_THRESH_BINARY); // 二值化
// CvMemStorage * storage = cvCreateMemStorage(0);
// CvSeq * contour = 0;
//cvFindContours(img,storage,&contour,sizeof(CvContour),1,2);
CvBox2D box=findRectContours(img);
mt.End();
cout<<box.center.x<<endl<<box.center.y<<endl<<box.size.height<<endl<<box.size.width<<endl<<mt.costTime<<endl;
cvDrawCircle(img,cvPoint(box.center.x,box.center.y),1,cvScalar(255,255,255),2,8,0);
cvNamedWindow("img", CV_WINDOW_AUTOSIZE );
cvShowImage( "img", img);//显示图像
cvReleaseImage(&img);
cvWaitKey(0);
}
CvBox2D findRectContours(const IplImage *gray)
{
CvBox2D box;
CvSeq* firstContour = NULL;
CvMemStorage* storage = cvCreateMemStorage(0);
IplImage* contourImg = cvCreateImage(cvGetSize(gray), gray->depth, 1);
cvCopy(gray, contourImg);
cvFindContours(contourImg, storage, &firstContour, sizeof(CvContour), 1,2);
CvSeq* maxContour = firstContour;
CvSeq* Contour = firstContour;
while(Contour)
{
if(maxContour->total < Contour->total)
{
maxContour = Contour;
}
Contour = Contour->h_next;
}
if(maxContour)
{
box = cvFitEllipse2(maxContour);
// CvPoint2D32f cross;
// float radius;
//cvMinEnclosingCircle(maxContour,&cross,&radius);
// cout<<cross.x<<endl<<cross.y<<endl;
//box.center.x=cross.x;box.center.y=cross.y;box.size.width=radius;
}
//cvDrawContours(contourImg,maxContour,cvScalar(0,0,255),cvScalar(0,0,255),1,1,0,cvPoint(0,0));
cvReleaseMemStorage(&storage);
return box;
}
/*======================================================================*/
/* OTSU global thresholding routine */
/*======================================================================*/
int otsu2 (IplImage *image)
{
int w = image->width;
int h = image->height;
unsigned char*np; // 图像指针
unsigned char pixel;
int thresholdValue=1; // 阈值
int ihist[256]; // 图像直方图,256个点
int i, j, k; // various counters
int n, n1, n2, gmin, gmax;
double m1, m2, sum, csum, fmax, sb;
// 对直方图置零...
memset(ihist, 0, sizeof(ihist));
gmin=255; gmax=0;
// 生成直方图
for (i =0; i < h; i++)
{
np = (unsigned char*)(image->imageData + image->widthStep*i);
for (j =0; j < w; j++)
{
pixel = np[j];
ihist[ pixel]++;
if(pixel > gmax) gmax= pixel;
if(pixel < gmin) gmin= pixel;
}
}
// set up everything
sum = csum =0.0;
n =0;
for (k =0; k <=255; k++)
{
sum += k * ihist[k]; /* x*f(x) 质量矩*/
n += ihist[k]; /* f(x) 质量 */
}
if (!n)
{
// if n has no value, there is problems...
//fprintf (stderr, "NOT NORMAL thresholdValue = 160\n");
thresholdValue =160;
goto L;
}
// do the otsu global thresholding method
fmax =-1.0;
n1 =0;
for (k =0; k <255; k++)
{
n1 += ihist[k];
if (!n1) { continue; }
n2 = n - n1;
if (n2 ==0) { break; }
csum += k *ihist[k];
m1 = csum / n1;
m2 = (sum - csum) / n2;
sb = n1 * n2 *(m1 - m2) * (m1 - m2);
/* bbg: note: can be optimized. */
if (sb > fmax)
{
fmax = sb;
thresholdValue = k;
}
}
L:
for (i =0; i < h; i++)
{
np = (unsigned char*)(image->imageData + image->widthStep*i);
for (j =0; j < w; j++)
{
if(np[j] >= thresholdValue)
np[j] =255;
else np[j] =0;
}
}
//cout<<"The Threshold of this Image in Otsu is:"<<thresholdValue<<endl;
return(thresholdValue);
}