1. 程式人生 > >用最大方差閾值法獲取灰度影象的最佳閾值

用最大方差閾值法獲取灰度影象的最佳閾值

1.獲取灰度影象的直方圖

 1 /*********************************************************************************
 2 * 函式名稱: APP_CameraCalibration_GetHistogram
 3 * 功能描述: 獲取灰度影象的直方圖
 4 * 函式引數: p_img_buff: 影象資料地址
 5                 len:影象資料長度
 6                 p_histogram:直方圖資料地址,大小為gray_level
 7                 gray_level:影象灰度等級
8 * 函式返回 TRUE,獲取成功,FALSE,獲取失敗 9 * 建立日期: 10 * 作 者: 11 ********************************************************************************** 12 */ 13 BOOL APP_CameraCalibration_GetHistogram(u8 *p_img_buff,s32 len,s32 *p_histogram,s32 gray_level) 14 { 15 s32 i; 16 17 if(!p_img_buff||!p_histogram||!len||!gray_level)
18 { 19 return FALSE; 20 } 21 memset(p_histogram,0,gray_level*sizeof(s32)); 22 23 for(i=0;i<len;i++) 24 { 25 if(*(p_img_buff+i) > gray_level -1) 26 { 27 return FALSE; 28 } 29 p_histogram[*(p_img_buff+i)]++;
30 } 31 return TRUE; 32 }
View Code

 2.用最大方差閾值法獲取影象的最佳閾值

/*********************************************************************************
* 函式名稱: APP_CameraCalibration_GetMaxVarianceThreshold
* 功能描述: 用最大方差閾值法獲取影象的最佳閾值,以便後續將影象分割
* 函式引數:  p_histogram:直方圖地址
                  gray_level:灰度等級   
                 p_threshold:輸出閾值
函式返回:    TRUE,獲取成功,FALSE,獲取失敗
* 建立日期: 
* 作    者: 
**********************************************************************************
*/
BOOL APP_CameraCalibration_GetMaxVarianceThreshold(s32 const * const p_histogram,s32 gray_level,s32 *p_threshold)
{
    //公式為δ²(T) = w0*w1*(μ1 - μ0)²,閾值T在1到gray_level-1之間變化,δ²(T)最大時即為所求
    //其中δ²(T)為方差,w0 為第0組概率,w1為第1組概率,μ0是第0組平均值,μ1是第1組平均值
    fp32 w0,Pi,w1,u0,u1,dt,max_dt;
    s32 T,i,max_pix;

    max_pix = 0;//總畫素個數
    for(i=0;i<gray_level;i++)
    {
        max_pix += p_histogram[i];//把每個灰度級上的畫素累積起來,就得到了總畫素個數,也是影象大小
    }

    max_dt = 0.0;
    *p_threshold = 0;
    for(T=1;T<gray_level;T++)
    {
        //計算累積頻率w0和w1
        w0 = 0.0;
        for(i=0;i<T-1;i++)
        {
            Pi = (fp32)((p_histogram[i]*1.0)/max_pix); //在灰度級i上,畫素出現的頻率
            w0 += Pi;//計算累積頻率

        }
        //CAL_VTCOM_Log(E_SysLogType_Debug," w0:%f\n",w0);
        w1 = 1 - w0;
        //平均值
        u0 = 0.0;
        u1 = 0.0;
        for(i=0;i<T-1;i++)
        {
            Pi = (fp32)((p_histogram[i]*1.0)/max_pix); //在灰度級i上,畫素出現的頻率

            u0 += (i*Pi)/w0;
        }

        for(i=T;i<gray_level;i++)
        {
            Pi = (fp32)((p_histogram[i]*1.0)/max_pix); //在灰度級i上,畫素出現的頻率
            u1 += (i*Pi)/w1;
        }

        dt = w0*w1*(u1-u0)*(u1-u0);
        if(dt>max_dt)
        {
            max_dt = dt;
            *p_threshold = T;
        }
    }
    return TRUE;
}
View Code