證明:
設r是灰度級,s是均衡化後的灰度級,範圍是0-L(L一般是255), 對圖像進行統計,設均衡化前的灰度級的隨機變量爲X,概率密度函數爲,均衡化後的隨機變量爲Y,概率密度函數爲。我們通過統計已知X的概率分佈,即已經知道了,設變換函數爲s = T(r), 那麼可以通過知道隨機變量Y的分佈函數
對(1)式兩邊求導的
因爲均衡化後要求隨機變量Y是均勻分佈的,所以 = 1/L,帶入(2)式得ds = L*dr ,對兩邊積分得
對於離散的隨機變量,積分換成求和便是了
雖然直方圖均衡化可能會出現“簡併”現象,即頻率較小的幾個灰度級可能合併成一個灰度級,但是灰度級間隔拉大了,頻率較大的灰度級被映射到間隔距離更大的灰度級,增強了圖像對比度。
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat src;
src = imread("f:\\圖片\\小包總.jpg");
if (src.data)
{
int b[256] = { 0 }, g[256] = { 0 }, r[256] = { 0 }; //定義數組統計bgr通道的灰度值
//統計頻數
Mat_<Vec3b>::iterator it_b = src.begin<Vec3b>();
Mat_<Vec3b>::iterator it_e = src.end<Vec3b>();
for (Mat_<Vec3b>::iterator it = it_b; it != it_e; it++)
{
b[(*it)[0]]++;
g[(*it)[1]]++;
r[(*it)[2]]++;
}
//均衡化
int m_size = src.rows*src.cols;
double sum[3] = { 0 };
for (int i = 0; i < 256; i++)
{
sum[0] += b[i];
b[i] = (sum[0] / m_size) * 255;
sum[1] += g[i];
g[i] = (sum[1] / m_size) * 255;
sum[2] += r[i];
r[i] = (sum[2] / m_size) * 255;
}
//創建均衡化後的圖像
Mat dst = src.clone();
Mat_<Vec3b>::iterator it_b1 = dst.begin<Vec3b>();
Mat_<Vec3b>::iterator it_e1 = dst.end<Vec3b>();
for (Mat_<Vec3b>::iterator it1 = it_b1, it = it_b; it1 != it_e1&&it != it_e; it++, it1++)
{
(*it1)[0] = b[(*it)[0]];
(*it1)[1] = b[(*it)[1]];
(*it1)[2] = b[(*it)[2]];
}
namedWindow("原圖像");
namedWindow("均衡化後");
imshow("原圖像", src);
imshow("均衡化後", dst);
}
waitKey(0);
return 0;
}