基于C++的OpenCV4入门基础--图像直方图均衡化

本文介绍了图像直方图均衡化的原理,它通过非线性拉伸重新分配图像像素值,使直方图分布均匀,增强图像对比度。OpenCV中的cv2.equalizeHist函数可用于实现这一过程。代码示例展示了如何从RGB图像转换为灰度图,再进行直方图均衡化处理。
摘要由CSDN通过智能技术生成

1,均衡化原理
直方图均衡化的基本原理是:
直方图均衡化是一种简单有效的图像增强技术。根据直方图的形态可以判断图像的质量,通过调控直方图的形态可以改善图像的质量。

直方图均衡化是将原始图像通过函数变换,调控图像的灰度分布,得到直方图分布合理的新图像,以此来调节图像亮度、增强动态范围偏小的图像的对比度。

由于人眼视觉特性,直方图均匀分布的图像视觉效果较好。直方图均衡化的基本思想是对图像中占比大的灰度级进行展宽,而对占比小的灰度级进行压缩,使图像的直方图分布较为均匀,扩大灰度值差别的动态范围,从而增强图像整体的对比度。

因此,直方图均衡化就是对图像进行非线性拉伸,重新分配图像像素值,本质上是根据直方图对图像进行线性或非线性灰度变换。

例如,直方图均衡化可以把原始图像的直方图调整到均匀分布,增加像素之间灰度值差别的动态范围,从而增强图像整体的对比度。
在这里插入图片描述
(1)计算原始灰度图像的直方图;

(2)通过直方图累加计算原始图像的累计分布函数 CDF;

(3)基于累计分布函数 CDF,通过插值计算得到新的灰度值。

OpenCV 提供了函数 cv2. equalizeHist 可以实现直方图均衡化。

函数说明:

CV_EXPORTS_W void equalizeHist( InputArray src, OutputArray dst );

参数说明:

src:输入图像
返回值 dst:输出图像,直方图均衡化
PS: 此API只接受灰度图

2,代码示例:
图像均衡化处理并进行直方图统计显示:首先读取RGB彩色三通道图,然后通过cvtColor进行彩色图转灰度图,然后对灰度图进行均衡化,通过直方图可以看到灰度图gray和均衡化后的灰度图dst的差别

	Mat src = imread("F:/code/images/aero1.jpg");
	if (src.empty()) {
		printf("fail to read");
		return -1;
	}
	namedWindow("input", WINDOW_AUTOSIZE);
	imshow("input", src);

	//直方图均衡化
	Mat gray, dst;
	cvtColor(src, gray, COLOR_BGR2GRAY);
	imshow("gray", gray);
	equalizeHist(gray, dst);//只能接受灰度图
	imshow("eh-demo", dst);

	//直方图计算

	//设定像素取值范围
	int histSize = 256;
	float range[] = { 0,255 };
	const float* histRanges = { range };

	Mat gray_hist, dst_hist;

	calcHist(&gray, 1, 0, Mat(), gray_hist, 1, &histSize, &histRanges, true, false);
	calcHist(&dst, 1, 0, Mat(), dst_hist, 1, &histSize, &histRanges, true, false);

	//创建直方图画布并归一化处理
	Mat histImage = Mat::zeros(Size(600, 400), CV_8UC3);
	int margin = 50;
	int nm = histImage.rows - 2 * margin;
	float bh = (float)(histImage.cols - 2 * margin) / (float)histSize;

	normalize(gray_hist, gray_hist, 0, nm, NORM_MINMAX, -1, Mat());//使用最小值和最大值进行归一化处理,最小值是0,最大值是nm
	normalize(dst_hist, dst_hist, 0, nm, NORM_MINMAX, -1, Mat());

	//绘制前后两个统计点
	for (int i = 0; i < histSize - 1; i++) {
		line(histImage, Point(i * bh + margin, nm - gray_hist.at<float>(i) + margin),
			Point((i + 2) * bh + margin, nm - gray_hist.at<float>(i + 1) + margin), Scalar(255, 0, 0), 1, LINE_AA);
		line(histImage, Point(i * bh + margin, nm - dst_hist.at<float>(i) + margin),
			Point((i + 2) * bh + margin, nm - dst_hist.at<float>(i + 1) + margin), Scalar(0, 255, 0), 1, LINE_AA);
	}
	imshow("histImage", histImage);

在这里插入图片描述
你的鼓励将是我创作的最大动力
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孤舟簔笠翁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值