/*---------------------------------------------------------------------------*//*基本全域閥值法*/ IplImage* imgBasicGlobalThreshold = cvCreateImage(cvGetSize(imgGrey),IPL_DEPTH_8U,1); cvCopyImage(srcImgGrey,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("BasicGlobalThreshold", CV_WINDOW_AUTOSIZE ); cvShowImage( "BasicGlobalThreshold", imgBasicGlobalThreshold);//顯示映像 cvReleaseImage(&imgBasicGlobalThreshold);/*---------------------------------------------------------------------------*//*上下閥值法:利用常態分佈求可信區間*/ IplImage* imgTopDown = cvCreateImage( cvGetSize(imgGrey), IPL_DEPTH_8U, 1 ); cvCopyImage(srcImgGrey,imgTopDown); CvScalar mean ,std_dev;//平均值、 標準差double u_threshold,d_threshold; cvAvgSdv(imgTopDown,&mean,&std_dev,NULL); u_threshold = mean.val[0] +2.5* std_dev.val[0];//上閥值 d_threshold = mean.val[0] -2.5* std_dev.val[0];//下閥值//u_threshold = mean + 2.5 * std_dev; //錯誤//d_threshold = mean - 2.5 * std_dev; cout<<"The TopThreshold of this Image in TopDown is:"<<d_threshold<<endl;//輸出顯示閥值 cout<<"The DownThreshold of this Image in TopDown is:"<<u_threshold<<endl; cvThreshold(imgTopDown,imgTopDown,d_threshold,u_threshold,CV_THRESH_BINARY_INV);//上下閥值 cvNamedWindow("imgTopDown", CV_WINDOW_AUTOSIZE ); cvShowImage( "imgTopDown", imgTopDown);//顯示映像 cvReleaseImage(&imgTopDown);/*---------------------------------------------------------------------------*//*迭代法*/ IplImage* imgIteration = cvCreateImage( cvGetSize(imgGrey), IPL_DEPTH_8U, 1 ); cvCopyImage(srcImgGrey,imgIteration);int thre3,nDiffRec; thre3 =DetectThreshold(imgIteration, 100, nDiffRec); cout<<"The Threshold of this Image in imgIteration is:"<<thre3<<endl;//輸出顯示閥值 cvThreshold(imgIteration,imgIteration,thre3,255,CV_THRESH_BINARY_INV);//上下閥值 cvNamedWindow("imgIteration", CV_WINDOW_AUTOSIZE ); cvShowImage( "imgIteration", imgIteration); cvReleaseImage(&imgIteration);
/*======================================================================*//* 迭代法*//*======================================================================*/// nMaxIter:最大迭代次數;nDiffRec:使用給定閥值確定的亮區與暗區平均灰階差異值int DetectThreshold(IplImage*img, int nMaxIter, int& iDiffRec) //閥值分割:迭代法{//映像資訊int height = img->height;int width = img->width;int step = img->widthStep/sizeof(uchar); uchar *data = (uchar*)img->imageData; iDiffRec =0;int F[256]={ 0 }; //長條圖數組int iTotalGray=0;//灰階值和int iTotalPixel =0;//像素數和byte bt;//某點的像素值 uchar iThrehold,iNewThrehold;//閥值、新閥值 uchar iMaxGrayValue=0,iMinGrayValue=255;//原映像中的最大灰階值和最小灰階值 uchar iMeanGrayValue1,iMeanGrayValue2;//擷取(i,j)的值,存於長條圖數組Ffor(int i=0;i<width;i++) {for(int j=0;j<height;j++) { bt = data[i*step+j];if(bt<iMinGrayValue) iMinGrayValue = bt;if(bt>iMaxGrayValue) iMaxGrayValue = bt; F[bt]++; } } iThrehold =0;// iNewThrehold = (iMinGrayValue+iMaxGrayValue)/2;//初始閥值 iDiffRec = iMaxGrayValue - iMinGrayValue;for(int a=0;(abs(iThrehold-iNewThrehold)>0.5)&&a<nMaxIter;a++)//迭代中止條件 { iThrehold = iNewThrehold;//小於當前閥值部分的平均灰階值for(int i=iMinGrayValue;i<iThrehold;i++) { iTotalGray += F[i]*i;//F[]儲存映像資訊 iTotalPixel += F[i]; } iMeanGrayValue1 = (uchar)(iTotalGray/iTotalPixel);//大於當前閥值部分的平均灰階值 iTotalPixel =0; iTotalGray =0;for(int j=iThrehold+1;j<iMaxGrayValue;j++) { iTotalGray += F[j]*j;//F[]儲存映像資訊 iTotalPixel += F[j]; } iMeanGrayValue2 = (uchar)(iTotalGray/iTotalPixel); iNewThrehold = (iMeanGrayValue2+iMeanGrayValue1)/2; //新閥值 iDiffRec = abs(iMeanGrayValue2 - iMeanGrayValue1); }//cout<<"The Threshold of this Image in imgIteration is:"<<iThrehold<<endl;return iThrehold;}
/*============================================================================= 代碼內容:基本全域閾值法 ==============================================================================*/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); // 返回閾值}