數組圖像處理:直方圖均衡化

證明:

        設r是灰度級,s是均衡化後的灰度級,範圍是0-L(L一般是255), 對圖像進行統計,設均衡化前的灰度級的隨機變量爲X,概率密度函數爲p_{r}(r),均衡化後的隨機變量爲Y,概率密度函數爲p_{s}(s)。我們通過統計已知X的概率分佈,即已經知道了p_{r}(r),設變換函數爲s = T(r), 那麼可以通過p_{r}(r)知道隨機變量Y的分佈函數

F_{Y}(s) = P(Y < s) = P(X < r) = \int_{-\infty }^{r}p_{r}(t)dt\cdots \cdots (1)

        對(1)式兩邊求導的

p_{s}(s) = [p_{r}(r)*\frac{\mathrm{d} r}{\mathrm{d} s}]\cdots \cdots (2)

        因爲均衡化後要求隨機變量Y是均勻分佈的,所以 p_{s}(s) = 1/L,帶入(2)式得ds = L*p_{r}(r)dr ,對兩邊積分得

T(r) = s = L\int_{0}^{r}p_{r}(\omega )d\omega\cdots \cdots (3)

         對於離散的隨機變量,積分換成求和便是了

 

        雖然直方圖均衡化可能會出現“簡併”現象,即頻率較小的幾個灰度級可能合併成一個灰度級,但是灰度級間隔拉大了,頻率較大的灰度級被映射到間隔距離更大的灰度級,增強了圖像對比度。

#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;
}

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