閾值分割:基本全域閥值法、上下閥值法、迭代法

來源:互聯網
上載者:User


/*---------------------------------------------------------------------------*//*基本全域閥值法*/    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);                              //  返回閾值}



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.