直方图均衡原理及opencv实现

直方图均衡化通过累计分布函数转换,使得图像灰度级分布均匀,提高图像对比度。在OpenCV中,可以通过离散变换形式的公式实现这一过程,代码操作后可观察到图像的明显变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        直方图均衡化处理技术是用累计分布函数作变换函数的直方图修正方法,用累积分布函数作为变换函数可产生一幅灰度级分布具有均匀概率密度的图像。其在数学上的变换函数如下:

其中,w 是积分的假变量。r 表示待处理图像的灰度,区间为[0,L-1],且 r = 0 表示黑色,r = L-1 表示白色。s 表示已处理图像的灰度,区间为[0,L-1],且 s = 0 表示黑色,s = L-1 表示白色。公式右边是随机变量 r 的累积分布函数。

该变换的离散变换形式为:

其中,MN 是图像中像素的总数,nk 是灰度为 rk的像素个数。与 rk 相对的 Pr(rk)图形通常称为直方图。


     使用opencv实现,其代码如下:

#include <iostream>
#include <opencv2/opencv.hpp>


using namespace cv;
using namespace std;

/* 输入原图,画出该图的直方图 */
int DrawHist(Mat image1, Mat* hist1)
{
	// 获取直方图
	int histsize[] = { 256 };   // 项的数量
	float range[] = { 0,256 };  // 像素值的范围
	const float *ranges[] = { range };
	int channels[] = { 0 };  // 通道

	Mat hist;  // 直方图结果
	calcHist(&image1, 1, channels, Mat(), hist, 1, histsize, ranges);

	// 以图形方式显示直方图
	// 获取最大值和最小值
	double maxVal = 0;
	double minVal = 0;
	minMaxLoc(hist, &minVal, &maxVal, 0, 0);

	// 显示直方图的图像
	Mat hist_img(256, 256, CV_8U, Scalar(255));

	// 设置最高点为图的90%
	int high_pt = static_cast<int>(0.9 * 256);

	// 每个条目绘制一条垂直线
	for (int h = 0; h < 256; h++) {
		float binVal = hist.at<float>(h);
		int intensity = static_cast<int>(binVal*high_pt / maxVal);
		line(hist_img, Point(h, 256), Point(h, 256 - intensity),Scalar::all(0));
	}
	hist_img.copyTo(*hist1);

	return 0;
	
}

int main(int argc, char* argv[]) {
	
	// 读入图片
	Mat image1 = imread("2.tif"),image2;

	// 把图片转为灰度图
	cvtColor(image1, image1, CV_RGB2GRAY);

	// 直方图均衡化前后直方图
	Mat hist1,hist2;

	DrawHist(image1, &hist1);

	equalizeHist(image1, image2);

	DrawHist(image2, &hist2);

	Mat image(image1.rows, image1.cols * 2+5, CV_8U);
	Mat hist(hist1.rows, hist1.cols * 2+5, CV_8U);

	image1.copyTo(image(Rect(0, 0, image1.cols, image1.rows)));
	image2.copyTo(image(Rect(image1.cols+5,0, image1.cols, image1.rows)));

	hist1.copyTo(hist(Rect(0, 0, hist1.cols, hist1.rows)));
	hist2.copyTo(hist(Rect(hist1.cols+5,0, hist1.cols, hist1.rows)));

	imshow("原图及直方图均衡化后的图", image);
	imshow("原图直方图及均衡后的直方图",hist);
	
	waitKey(0);
	return 0;
}


结果如下:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值