視訊、圖形影象處理之Opencv技術記錄(六)、均衡直方圖
阿新 • • 發佈:2019-01-31
目標
在本教程中,您將學習:
- 什麼是影象直方圖以及為什麼它有用
理論
什麼是影象直方圖?
- 它是影象強度分佈的圖形表示。
- 它量化了所考慮的每個強度值的畫素數。
什麼是直方圖均衡?
- 這是一種改善影象對比度的方法,以便拉伸強度範圍(另請參閱相應的維基百科條目)。
- 為了更清楚,從上面的影象中,您可以看到畫素似乎聚集在可用的強度範圍的中間。直方圖均衡的作用是延伸此範圍。請看下圖:綠色圓圈表示人口密集的強度。應用均衡後,我們得到一個直方圖,如中間的數字。生成的影象顯示在右側的圖片中。
它是如何工作的?
- 均衡意味著將一個分佈(給定的直方圖)對映到另一個分佈(更寬和更均勻的強度值分佈),因此強度值分佈在整個範圍內。
-
要實現均衡效果,重對映應該是累積分佈函式(cdf)(更多細節,請參閱學習OpenCV)。對於直方圖,其累積分佈是:
要將其用作重新對映函式,我們必須對進行歸一化,使得最大值為255(或影象強度的最大值)。從上面的例子中,累積函式是:
-
最後,我們使用簡單的重新對映程式來獲得均衡影象的強度值:
碼
C ++
- 這個程式做了什麼?
- 載入影象
- 將原始影象轉換為灰度
- 在視窗中顯示源影象和均衡影象。
- 可下載的程式碼:點選這裡
- 程式碼一目瞭然:
#include "opencv2/imgcodecs.hpp" #include "opencv2/highgui.hpp" #include "opencv2/imgproc.hpp" #include <iostream> using namespace cv; using namespace std; int main( int argc, char** argv ) { CommandLineParser parser( argc, argv, "{@input | ../data/lena.jpg | input image}" ); Mat src = imread( parser.get<String>( "@input" ), IMREAD_COLOR ); if( src.empty() ) { cout << "Could not open or find the image!\n" << endl; cout << "Usage: " << argv[0] << " <Input image>" << endl; return -1; } cvtColor( src, src, COLOR_BGR2GRAY ); Mat dst; equalizeHist( src, dst ); imshow( "Source image", src ); imshow( "Equalized Image", dst ); waitKey(); return 0; }
說明
C ++
- 載入源影象:
CommandLineParser parser( argc, argv, "{@input | ../data/lena.jpg | input image}" ); Mat src = imread( parser.get<String>( "@input" ), IMREAD_COLOR ); if( src.empty() ) { cout << "Could not open or find the image!\n" << endl; cout << "Usage: " << argv[0] << " <Input image>" << endl; return -1; }
- 將其轉換為灰度:
cvtColor( src, src, COLOR_BGR2GRAY );
Mat dst;
equalizeHist( src, dst );
由於可以很容易地看到,唯一的引數是原始影象和輸出(均衡)影象。
- 顯示兩個影象(原始影象和均衡影象):
imshow( "Source image", src );
imshow( "Equalized Image", dst );
- 等到使用者存在該程式
waitKey();
結果
-
為了更好地理解均衡的結果,讓我們介紹一個對比度不大的影象,例如:
順便說一下,這個直方圖:
請注意,畫素聚集在直方圖的中心周圍。
-
在我們的程式中應用均衡後,我們得到了這個結果:
這個形象肯定有更多的對比。看看它的新直方圖如下:
請注意畫素數在強度範圍內的分佈情況。