直方圖均衡化

       最近在研究岡薩雷斯的那本《數字圖像處理》,發現此書確實不錯。看到直方圖均衡這一章,順便研究了下OpenCV的源代碼。

       直方圖均衡化是一個很強大的自適應對比度增強工具。

       詳細的說明可以見《數字圖像處理.第三版》(岡薩雷斯)英文版 P144。

       一個灰度值在一幅圖像中出現的概率可以表示如下:

                   ------------(1)

      注: L表示灰度級別,8位灰度圖的L=256.

   

   -----------------------(2)

     注:T()表示一個灰度變換函數,滿足單調性。nj表示灰度j在圖像中出現的次數。

     由公式(2)可以得到每個輸入圖像的灰度對應輸出圖像的灰度值,對sk四捨五入。

     詳細的證明可以參考書上。

     最後查看了下OpenCV的源代碼。

     查看源代碼:可以進入OpenCV的安裝目錄,打開OpenCV.sln 這個工程文件。利用vs2008自帶的搜索工具,搜索關鍵字 cvEqualizeHist。

     附上OpenCV直方圖均衡化的源碼。

    

CV_IMPL void cvEqualizeHist( const CvArr* srcarr, CvArr* dstarr )
{
    CvMat sstub, *src = cvGetMat(srcarr, &sstub);
    CvMat dstub, *dst = cvGetMat(dstarr, &dstub);
    
    CV_Assert( CV_ARE_SIZES_EQ(src, dst) && CV_ARE_TYPES_EQ(src, dst) &&
               CV_MAT_TYPE(src->type) == CV_8UC1 );
    CvSize size = cvGetMatSize(src);
    if( CV_IS_MAT_CONT(src->type & dst->type) )
    {
        size.width *= size.height;
        size.height = 1;
    }
    int x, y;
    const int hist_sz = 256;
    int hist[hist_sz];
    memset(hist, 0, sizeof(hist));
    
    for( y = 0; y < size.height; y++ )
    {
        const uchar* sptr = src->data.ptr + src->step*y;
        for( x = 0; x < size.width; x++ )
            hist[sptr[x]]++;
    }
    
    float scale = 255.f/(size.width*size.height);
    int sum = 0;
    uchar lut[hist_sz+1];

    for( int i = 0; i < hist_sz; i++ )
    {
        sum += hist[i];
        int val = cvRound(sum*scale);
        lut[i] = CV_CAST_8U(val);
    }

    lut[0] = 0;
    for( y = 0; y < size.height; y++ )
    {
        const uchar* sptr = src->data.ptr + src->step*y;
        uchar* dptr = dst->data.ptr + dst->step*y;
        for( x = 0; x < size.width; x++ )
            dptr[x] = lut[sptr[x]];
    }
}


    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章