直方图均衡化C++实现

直方图均衡化主要是为了增强图像的对比度,是直方图分布更加均匀

概念可以参考其他博客的介绍。

主要分为以下几个主要步骤:

1.统计每一个灰度级的像素总数
2.计算每一个灰度级的概率(P(valueNumber)/piexelNumber,该灰度级像素除以像素总数)
3.累积概率,例如:p1=0.01,p2=0.01,p3=0.02,则累积概率为p1 p1+p2 p1+p2+p3;
4.将灰度值映射为: 灰度级*该灰度级累积概率值

原图:
在这里插入图片描述
直方图均衡化之后:
在这里插入图片描述
代码如下:

#include "opencv2/opencv.hpp"
#include "opencv2/core.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "iostream"
using namespace cv;
using namespace std;

bool EqualizeHist(Mat gray, Mat result)
{
	map<int, int>mp;
	for (int i = 0; i < gray.rows; i++)
	{
		uchar* ptr = (uchar*)gray.data + i * gray.cols;
		for (int j = 0; j < gray.cols; j++)
		{
			int value = ptr[j];
			mp[value]++;
		}
	}
	map<int, double>valuePro;
	double sumPro = 0.0;
	int sumPixel = gray.cols*gray.rows;
	for (int i = 0; i < 256; i++)
	{
		sumPro += (1.0*mp[i]) / sumPixel;
		valuePro[i] = sumPro;
	}
	for (int i = 0; i < gray.rows; i++)
	{
		uchar* ptr1 = (uchar*)gray.data + i * gray.cols;
		for (int j = 0; j < gray.cols; j++)
		{
			int value = ptr1[j];
			double p = valuePro[value];
			result.at<uchar>(i, j) = value * p;
		}
	}
	return true;
}



int main()
{
	Mat srcImage = imread("IMG4_MRF_focus.tif");
	Mat image = imread("IMG4_MRF_focus.tif");
	Mat imageRGB[3];
	split(srcImage, imageRGB);
	//Mat image1[3];
	for (int i = 0; i < 3; i++)
	{
		EqualizeHist(imageRGB[i], imageRGB[i]);
	}
	merge(imageRGB,3, srcImage);
	imshow("原图", image);
	imshow("直方图", srcImage);
	waitKey();
	return 0;
}
图像直方图均衡化是一种用于增强图像对比度的技术,它通过对图像的像素值进行调整,使得图像中的亮度分布更均匀。下面是一个简单的C++实现原理: 1. 首先,计算图像的灰度直方图,即统计每个灰度级别的像素数量。 2. 根据直方图,计算每个灰度级别的累积分布函数(CDF),表示灰度级别小于等于当前级别的像素所占的比例。 3. 根据CDF,计算每个灰度级别的映射表,将原始图像的每个像素值映射到新的像素值上。映射表的计算公式为: new_value = round((L-1) * CDF(old_value)) 其中,L表示灰度级别的数量,CDF(old_value)表示旧像素值对应的累积分布函数值。 4. 遍历原始图像的每个像素,根据映射表将其像素值替换为新的像素值。 下面是一个简单的示例代码: ```cpp #include <iostream> #include <opencv2/opencv.hpp> using namespace cv; using namespace std; void histogramEqualization(Mat& image) { // 计算直方图 Mat hist; int histSize = 256; float range[] = {0, 256}; const float* histRange = {range}; calcHist(&image, 1, 0, Mat(), hist, 1, &histSize, &histRange, true, false); // 计算累积分布函数 Mat cdf; hist.copyTo(cdf); for (int i = 1; i < histSize; i++) { cdf.at<float>(i) += cdf.at<float>(i - 1); } cdf /= image.total(); // 计算映射表 Mat lut(1, histSize, CV_8UC1); for (int i = 0; i < histSize; i++) { lut.at<uchar>(i) = saturate_cast<uchar>((histSize - 1) * cdf.at<float>(i)); } // 应用映射表 LUT(image, lut, image); } int main() { // 读取图像 Mat image = imread("input.jpg", IMREAD_GRAYSCALE); if (image.empty()) { cout << "Failed to read image" << endl; return -1; } // 直方图均衡化 histogramEqualization(image); // 显示结果 imshow("Equalized Image", image); waitKey(0); return 0; } ``` 请注意,这只是一个简单的示例代码,实际应用中可能需要处理更多的细节,例如处理彩色图像、处理边界情况等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值