1. 程式人生 > >opencv影象直方圖均衡化及其原理

opencv影象直方圖均衡化及其原理

直方圖均衡化是什麼有什麼用

先說什麼是直方圖均衡化,通俗的說,以灰度圖為例,原圖的某一個畫素為x,經過某個函式變為y.形成新的圖.新的圖的灰度值的分佈是均勻的,這個過程就叫直方圖均衡化.

影象直方圖均衡化作用:用來增強對比度.

這種方法通常用來增加許多影象的全域性對比度,尤其是當影象的有用資料的對比度相當接近的時候。通過這種方法,亮度可以更好地在直方圖上分佈。這樣就可以用於增強區域性的對比度而不影響整體的對比度,直方圖均衡化通過有效地擴充套件常用的亮度來實現這種功能。
這種方法對於背景和前景都太亮或者太暗的影象非常有用,這種方法尤其是可以帶來X光影象中更好的骨骼結構顯示以及曝光過度或者曝光不足照片中更好的細節。這種方法的一個主要優勢是它是一個相當直觀的技術並且是可逆操作,如果已知均衡化函式,那麼就可以恢復原始的直方圖,並且計算量也不大。這種方法的一個缺點是它對處理的資料不加選擇,它可能會增加背景噪聲的對比度並且降低有用訊號的對比度。

先看直觀的效果,圖三變為圖四的過程,就利用了直方圖均衡化.

再來看看缺點:

對比度增強了,但是面部太亮,看不清楚了.

什麼是直方圖

其實就是離散的概率分佈圖. 比如256灰度圖.橫軸就是畫素值,從0-255,縱軸是當前畫素值對應的畫素個數.

是用以表示數字影象中亮度分佈的直方圖,標繪了影象中每個亮度值的畫素數。可以藉助觀察該直方圖瞭解需要如何調整亮度分佈。這種直方圖中,橫座標的左側為純黑、較暗的區域,而右側為較亮、純白的區域。因此,一張較暗圖片的影象直方圖中的資料多集中於左側和中間部分;而整體明亮、只有少量陰影的影象則相反。

直方圖均衡化的數學原理

文章開頭說了,以灰度圖為例,原圖的某一個畫素為x,經過某個函式變為y.形成新的圖.新的圖的灰度值的分佈是均勻的,這個過程就叫直方圖均衡化.
ok,比如現在我們拿到一個256灰度圖,我們知道什麼?

  • 畫素值是0-255,即能表達256種顏色.
  • 我們能統計出各個畫素值的畫素個數.即我們知道原圖的概率分佈
  • 我們希望生成的新圖的畫素值的概率分佈是平均分佈的.

我們要求的是一個函式T,可以使得畫素分佈從下面左圖變成右圖.其中L是畫素值的最大值+1.

先看一道數學題.

很簡單,已知x的概率分佈,及x,y的轉換關係,可以求得y的概率分佈.

怎麼把我們的問題轉換成數學題?$ F_x(x) \(就相當於已知的第二點,即原始圖片的畫素的概率分佈.,\)F_Y(y)\(就相當於已知的第三點.即轉換後的圖片的畫素要均勻分佈.現在要求的是\) y = T(x)$的這個T是什麼樣的.這樣就可以把原圖的畫素x,轉換成均衡化後的圖片的畫素y.

根據上面的數學題,我們可以繼續推導,得到s和r的關係.即我們所要求的轉換函式T

以上,就是做直方圖均衡化的數學原理.

opencv裡已經替我們封裝好了,就幾句程式碼的事情.

opencv怎麼實現直方圖均衡化

下面是將圖片轉換到hsv(色調,飽和度,亮度)空間再對v這一個channel做直方圖均衡化的一段程式碼.轉hsv不是必須的,只是這段程式碼後續還有判斷顏色的程式碼.所以先轉到了hsv.因為hsv空間比rgb空間更好判斷顏色.

    Mat img_hsv;
    cvtColor(roi_img,img_hsv,CV_BGR2HSV);
    vector<Mat> hsvSplit;
    split(img_hsv, hsvSplit);
    equalizeHist(hsvSplit[2],hsvSplit[2]);
    merge(hsvSplit,img_hsv);