直方圖均衡化(提升圖像的對比度)


直方圖均衡化

目標

在這個教程中你將學到:

  • 什么是圖像的直方圖和為什么圖像的直方圖很有用
  • 用OpenCV函數 equalizeHist 對圖像進行直方圖均衡化

原理

圖像的直方圖是什么?

  • 直方圖是圖像中像素強度分布的圖形表達方式.
  • 它統計了每一個強度值所具有的像素個數.
../../../../../_images/Histogram_Equalization_Theory_0.jpg

直方圖均衡化是什么?

  • 直方圖均衡化是通過拉伸像素強度分布范圍來增強圖像對比度的一種方法.
  • 說得更清楚一些, 以上面的直方圖為例, 你可以看到像素主要集中在中間的一些強度值上. 直方圖均衡化要做的就是 拉伸 這個范圍. 見下面左圖: 綠圈圈出了 少有像素分布其上的 強度值. 對其應用均衡化后, 得到了中間圖所示的直方圖. 均衡化的圖像見下面右圖.
../../../../../_images/Histogram_Equalization_Theory_1.jpg

直方圖均衡化是怎樣做到的?

  • 均衡化指的是把一個分布 (給定的直方圖) 映射 到另一個分布 (一個更寬更統一的強度值分布), 所以強度值分布會在整個范圍內展開.

  • 要想實現均衡化的效果, 映射函數應該是一個 累積分布函數 (cdf) (更多細節, 參考*學習OpenCV*). 對於直方圖 H(i), 它的 累積分布 H^{'}(i) 是:

    H^{'}(i) = \sum_{0 \le j < i} H(j)

    要使用其作為映射函數, 我們必須對最大值為255 (或者用圖像的最大強度值) 的累積分布 H^{'}(i) 進行歸一化. 同上例, 累積分布函數為:

    ../../../../../_images/Histogram_Equalization_Theory_2.jpg
  • 最后, 我們使用一個簡單的映射過程來獲得均衡化后像素的強度值:

    equalized( x, y ) = H^{'}( src(x,y) )

例程

  • 咋個例程是用來干嘛的?

    • 加載源圖像
    • 把源圖像轉為灰度圖
    • 使用OpenCV函數 EqualizeHist 對直方圖均衡化
    • 在窗體中顯示源圖像和均衡化后圖像.
  • 下載例程: 點擊 這里

  • 例程一瞥:

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace cv; using namespace std; /** @function main */ int main( int argc, char** argv ) { Mat src, dst; char* source_window = "Source image"; char* equalized_window = "Equalized Image"; /// 加載源圖像 src = imread( argv[1], 1 ); if( !src.data ) { cout<<"Usage: ./Histogram_Demo <path_to_image>"<<endl; return -1;} /// 轉為灰度圖 cvtColor( src, src, CV_BGR2GRAY ); /// 應用直方圖均衡化 equalizeHist( src, dst ); /// 顯示結果 namedWindow( source_window, CV_WINDOW_AUTOSIZE ); namedWindow( equalized_window, CV_WINDOW_AUTOSIZE ); imshow( source_window, src ); imshow( equalized_window, dst ); /// 等待用戶按鍵退出程序 waitKey(0); return 0; } 

說明

  1. 聲明原圖和目標圖以及窗體名稱:

    Mat src, dst; char* source_window = "Source image"; char* equalized_window = "Equalized Image"; 
  2. 加載源圖像:

    src = imread( argv[1], 1 ); if( !src.data ) { cout<<"Usage: ./Histogram_Demo <path_to_image>"<<endl; return -1;} 
  3. 轉為灰度圖:

    cvtColor( src, src, CV_BGR2GRAY ); 
  4. 利用函數 equalizeHist 對上面灰度圖做直方圖均衡化:

    equalizeHist( src, dst ); 

    可以看到, 這個操作的參數只有源圖像和目標 (均衡化后) 圖像.

  5. 顯示這兩個圖像 (源圖像和均衡化后圖像) :

    namedWindow( source_window, CV_WINDOW_AUTOSIZE ); namedWindow( equalized_window, CV_WINDOW_AUTOSIZE ); imshow( source_window, src ); imshow( equalized_window, dst ); 
  6. 等待用戶案件退出程序

    waitKey(0); return 0; 

結果

  1. 為了更好地觀察直方圖均衡化的效果, 我們使用一張對比度不強的圖片作為源圖像輸入, 如下圖:

    ../../../../../_images/Histogram_Equalization_Original_Image.jpg

    它的直方圖為:

    ../../../../../_images/Histogram_Equalization_Original_Histogram.jpg

    注意到像素大多集中在直方圖中間的強度上.

  2. 使用例程進行均衡化后, 我們得到下面的結果:

    ../../../../../_images/Histogram_Equalization_Equalized_Image.jpg

    這幅圖片顯然對比度更強. 再驗證一下均衡化后圖片的直方圖:

    ../../../../../_images/Histogram_Equalization_Equalized_Histogram.jpg

    注意到現在像素在整個強度范圍內均衡分布.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM