数组图像处理:直方图均衡化

证明:

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

猜你喜欢

转载自blog.csdn.net/qq_25974431/article/details/89577572