OpenCV 對比度受限的自適應直方圖均衡化(CLAHE) C++實現

直方圖均衡化(HE)是一種很常用的直方圖類方法,基本思想是通過圖像的灰度分佈直方圖確定一條映射曲線,用來對圖像進行灰度變換,以達到提高圖像對比度的目的。該映射曲線其實就是圖像的累計分佈直方圖(CDF)(嚴格來說是呈正比例關係)。然而HE是對圖像全局進行調整的方法,不能有效地提高局部對比度,而且某些場合效果會非常差。
對比度受限的自適應直方圖均衡(CLAHE,Contrast Limited Adaptive Histogram Equalization)算法。儘管最初它僅僅是被當作一種圖像增強算法被提出,但是現今在圖像去霧、低照度圖像增強,水下圖像效果調節、以及數碼照片改善等方面都有應用。這個算法的算法原理看似簡單,但是實現起來卻並不那麼容易。我們將結合相應的OpenCV代碼來對其進行解釋。

 

先來看一下待處理的圖像效果:

下面是利用CLAHE算法處理之後得到的兩個效果(後面我們還會具體介紹我們所使用的策略)

 

對於一幅圖像而言,它不同區域的對比度可能差別很大。可能有些地方很明亮,而有些地方又很暗淡。如果採用單一的直方圖來對其進行調整顯然並不是最好的選擇。於是人們基於分塊處理的思想提出了自適應的直方圖均衡算法AHE。維基百科上說的也比較明白:AHE improves on this by transforming each pixel with a transformation function derived from a neighbourhood region. 但是這種方法有時候又會將一些噪聲放大,這是我們所不希望看到的。於是荷蘭烏得勒支大學的Zuiderveld教授又引入了CLAHE,利用一個對比度閾值來去除噪聲的影響。特別地,爲了提升計算速度以及去除分塊處理所導致的塊邊緣過渡不平衡效應,他又建議採用雙線性插值的方法。關於算法的介紹和描述,下面這兩個資源已經講得比較清楚。

[1] https://en.wikipedia.org/wiki/Adaptive_histogram_equalization#Contrast_Limited_AHE

[2] K. Zuiderveld: Contrast Limited Adaptive Histogram Equalization. In: P. Heckbert: Graphics Gems IV, Academic Press 1994 (http://www.docin.com/p-119164091.html)

https://en.wikipedia.org/wiki/Adaptive_histogram_equalization

關於他的原理很多教程已經明白了,現在直說Opencv怎麼用它。

OpenCV中 CLAHE代碼地址如下:

/modules/imgproc/src/clahe.cpp

代碼使用

static void color_transfer_with_spilt( cv::Mat &input, std::vector<cv::Mat> &chls )
{
    cv::cvtColor( input, input, cv::COLOR_BGR2YCrCb);
    cv::split( input, chls );
}

static void color_retransfer_with_merge( cv::Mat &output, std::vector<cv::Mat> &chls )
{
    cv::merge( chls, output );
    cv::cvtColor( output, output, cv::COLOR_YCrCb2BGR );
}

cv::Mat clahe_deal( cv::Mat &src)
{
    cv::Mat ycrcb = src.clone();
    std::vector<cv::Mat> channels;

    color_transfer_with_spilt(ycrcb, channels);

    cv::Mat clahe_img;
    cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE();
    // 直方圖的柱子高度大於計算後的ClipLimit的部分被裁剪掉,然後將其平均分配給整張直方圖
    // 從而提升整個圖像
    clahe->setClipLimit(4.);    // (int)(4.*(8*8)/256)
    clahe->setTilesGridSize(Size(8, 8)); // 將圖像分爲8*8塊
    clahe->apply(channels[0], clahe_img);
    channels[0].release();
    clahe_img.copyTo(channels[0]);
    color_retransfer_with_merge(ycrcb, channels);
    return ycrcb;

}

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