其中涉及到图像二值化 开操作等
#include "cv.h"
#include "highgui.h"
using namespace cv;
double GetThreshhold(double count[])
{
//进行两次平滑
for(int i=0;i<2;i++)
{
double one=count[0],two=count[1],three=count[2];
for(int i=1;i<255;i++)
{
count[i]=(one+two+three)/3;
one=two;
two=three;
three=count[i+1];
}
}
double maxvalue=-1,lessMax=-1;
int maxPos=-1,lessMaxPos=-1;
//寻找最大峰值和次大峰值
for(int i=0;i<256;i++)
{
if(count[i]>maxvalue)
{
maxvalue=count[i];
maxPos=i;
}
}
for(int i=0;i<maxPos-20;i++)
{
if(count[i]>lessMax)
{
lessMax=count[i];
lessMaxPos=i;
}
}
for(int i=maxPos+20;i<256;i++)
{
if(count[i]>lessMax)
{
lessMax=count[i];
lessMaxPos=i;
}
}
int startPos=min(maxPos,lessMaxPos);
int endPos=max(maxPos,lessMaxPos);
double minValue=INT_MAX;
int minPos=-1;
for(int i=startPos;i<=endPos;i++)
{
if(count[i]<minValue)
{
minValue=count[i];
minPos=i;
}
}
return minPos;
}
void thresholdImage(Mat& mat,double th)
{
uchar* p=mat.data;
for(unsigned int i=0;i<mat.rows*mat.cols;i++)
*p++ = (*p>=th?255:0);
}
Point2f calcCenter(Mat& mat)
{
int nrows=mat.rows;
int ncols=mat.cols;
int area=0;
float xSum=0.0,ySum=0;
uchar* p;
//计算x方向
for(int i=0;i<nrows;i++)
{
p=mat.ptr<uchar>(i);
for(int j=0;j<ncols;j++)
{
if(p[j]==0)
{
area++;
xSum+=i;
ySum+=j;
}
}
}
Point2f ret;
ret.x=xSum/area;
ret.y=ySum/area;
return ret;
}
int main()
{
Mat image;
image=imread("circle.jpg",CV_LOAD_IMAGE_GRAYSCALE);
double count[256]={0.0};
uchar* p=image.data;
for(unsigned int i=0;i<image.rows*image.cols;i++)
{
count[*p]+=1.0;
p++;
}
//数值对数化
for(int i=0;i<256;i++)
count[i]=log(count[i]+1);
double threshold=GetThreshhold(count);
//将图片二值化
thresholdImage(image,threshold);
//填充白点 开操作
Mat element = getStructuringElement( MORPH_RECT,
Size(5,5 ));
//erode(image,image,element);
//dilate(image,image,element);
Mat element5(5,5,CV_8U,Scalar(1));
//morphologyEx(image,closed,cv::MORPH_CLOSE,element5);
morphologyEx(image,image,cv::MORPH_OPEN,element5);
//计算形心
Point2f center=calcCenter(image);
cvNamedWindow("test",CV_WINDOW_AUTOSIZE);
imshow("test",image);
waitKey(0);
return 0;
}