C++实现直方图均衡,附源代码

接口设计

//直方图均衡化函数定义
	static BOOL histeq(CImageDataset &imgIn, CImageDataset &imgOut); 

运行结果

在这里插入图片描述

源代码

//计算直方图函数
void CImageProcessingEx::getHist(const CImageDataset& img,int band,std::vector<int>& hist)
{
	int value;
	int N_row = img.m_ysize;
	int N_col = img.m_xsize;
	const double* imgData = img.m_data;
	for(int row=0; row<N_row; ++row)  //对图像逐行逐列进行扫描,计算完成直方图
	{ 
		for(int col=0; col<N_col; ++col) 
		{ 
			int index = band * N_row * N_col + row * N_col + col;
			value=(UINT8)imgData[index];
			hist[value]++; 
		} 
	} 
}


//直方图均衡
BOOL CImageProcessingEx::histeq(CImageDataset &imgIn, CImageDataset &imgOut) 
{ 
	const int LEVEL = 256; //灰度值级数
	int k, row, col; //用于循环
	//double hist[LEVEL], accuHist[LEVEL]; //直方图和累积直方图
	std::vector<int> hist(LEVEL);
	std::vector<double> accuHist(LEVEL);

	/* 确保输入图像非空 */ 
	if(imgIn.empty()) 
	{ 
		return FALSE; 
	} 

	//记录输入图像的尺寸
	init(imgIn);

	/*创建输出图像*/ 
	if(FALSE == imgOut.create(n_col,n_row,n_band))
	{ 
		return FALSE; 
	} 

	//输入和输出图像的数据区指针
	const double *input_data=imgIn.m_data;
	double *output_data = imgOut.m_data;
	int img_area = n_col * n_row;//面积,即单个波段的像素个数

	for (int band = 0; band < n_band; band++)
	{/*  步骤 1:计算输入图像的直方图  */
		getHist(imgIn, band,hist);

		/*  步骤 2:计算累积直方图  */
		accuHist[0] = hist[0] / img_area;
		for (k = 1; k < LEVEL - 1; k++) //对直方图索引进行扫描,计算完成累积直方图
		{
			accuHist[k] = accuHist[k - 1] + double(hist[k]) / img_area;
		}
		accuHist[255] = 1;

		/*  步骤 3:根据用累积直方图建立灰度变换函数,并逐行逐列进行像素的灰度变换 */
		int index, gray_value;
		for (row = 0; row < n_row; ++row)
		{
			for (col = 0; col < n_col; ++col)
			{
				index = coo2ind(band,row,col);
				gray_value = (int)input_data[index];

				output_data[index] = (LEVEL - 1) * accuHist[gray_value];//灰度变换
			}
		}
	}
	return TRUE;
}
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用OpenCV 4和C语言实现直方图均衡的示例代码: ```c #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main(int argc, char** argv) { // 读取图像 Mat img = imread("lena.jpg", IMREAD_GRAYSCALE); if (img.empty()) { cout << "Could not read the image: " << endl; return 1; } // 计算直方图 Mat hist; int histSize = 256; float range[] = { 0, 256 }; const float* histRange = { range }; calcHist(&img, 1, 0, Mat(), hist, 1, &histSize, &histRange, true, false); // 计算累积直方图 Mat cumHist(histSize, 1, CV_32FC1); cumHist.at<float>(0, 0) = hist.at<float>(0, 0); for (int i = 1; i < histSize; i++) { cumHist.at<float>(i, 0) = cumHist.at<float>(i - 1, 0) + hist.at<float>(i, 0); } // 直方图均衡化 Mat eqImg(img.size(), img.type()); float alpha = 255.0 / (img.rows * img.cols); for (int i = 0; i < img.rows; i++) { for (int j = 0; j < img.cols; j++) { int intensity = img.at<uchar>(i, j); eqImg.at<uchar>(i, j) = cvRound((cumHist.at<float>(intensity, 0) * alpha)); } } // 显示原图和均衡化后的图像 namedWindow("Original Image", WINDOW_AUTOSIZE); imshow("Original Image", img); namedWindow("Equalized Image", WINDOW_AUTOSIZE); imshow("Equalized Image", eqImg); waitKey(0); return 0; } ``` 该程序中,我们首先读取了一张灰度图像,并计算了其直方图。然后,我们使用累积直方图将图像进行直方图均衡化,并显示了原始图像和均衡化后的图像。在计算累积直方图时,我们使用了一个简单的迭代方法,即将当前像素的灰度级与前一个像素的灰度级相加,以便在每个灰度级上获得其累积值。最后,我们使用cvRound函数将每个像素的值四舍五入到最接近的整数,以便将其转换为8位无符号整数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值