圖像OTSU閾值化

#include "highgui.h"
#include "cv.h"
void otsu(const IplImage* src,IplImage* dest,double* his)//ousu二值化
{
int i,s=0,t,k=0;
double p[256]={0.0},w0=0.0,w1=0.0,u0=0.0,u1=0.0,u=0.0,g[256]={0.0},m0=0.0,m1=0.0,max=0.0,num=0.0;
int height=src->height;
int width=src->width;
s=height*width;
for(i=0;i<256;i++)
p[i]=his[i]/s;
for(t=0;t<256;t++)                                                                                                                                                                                                                                                                             



{
w0=w1=u0=u1=u=m0=m1=0.0;
   for(i=0;i<t;i++)
{
  w0=w0+p[i];
}
for(i=0;i<t;i++)
   m0 = m0+i*p[i];//printf("m0=%f\n",m0);
for(i=255;i>=t;i--)
m1=m1+i*p[i];
w1=1.0-w0;
u0=m0/w0;
u1=m1/w1;
u=m0+m1;
//g[t]=w0*(u0-u*u)+w1*(u1-u*u);
g[t]=(u*w0-m0)*(u*w0-m0)/(w0*w1);//printf("%f\n",g[t]);
}
max=g[1];
for(i=2;i<256;i++)
  if(max<g[i])
 max=g[i];
for(i=1;i<256;i++)
//{   printf("%f||%d\n",max,i);
if(max==g[i])break;
k=i;printf("otsu最佳閾值灰度爲%d",k);
cvThreshold(src,dest,k,255,CV_THRESH_BINARY);
}
int main(int argv,char** argc)
{
int i,j,s=0;
double his[256]={0.0};
IplImage* src=cvLoadImage("C:\\Users\\CDZHYF\\Desktop\\14.jpg",1);
IplImage*dest=cvCreateImage(cvGetSize(src),src->depth,src->nChannels);
IplImage*dst=cvCreateImage(cvGetSize(src),src->depth,src->nChannels);
IplImage*temp=cvCreateImage(cvGetSize(src),src->depth,src->nChannels);
int height=src->height;
int width=src->width;
for(i=0;i<height;i++)
for(j=0;j<width;j++)
his[CV_IMAGE_ELEM(src,uchar,i,j)]++;//histogram

otsu(src,dest,his);//otsu二值化
cvMorphologyEx(dest,dst,temp,NULL,CV_MOP_OPEN,1);//開運算


for(i=0;i<height;i++)
for(j=0;j<width;j++)
his[CV_IMAGE_ELEM(dst,uchar,i,j)]++;//histogram
s=his[255];printf("\n%d",s);


cvNamedWindow("otsu二值化",CV_WINDOW_AUTOSIZE);
cvShowImage("otsu二值化",dst);
cvWaitKey(0);
cvReleaseImage(&dst);
  cvDestroyWindow("otsu二值化");
return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章