直方图均衡化原理和编码实现(C/C++)

参考链接:http://hi.baidu.com/ghymark/item/ce52f8a7f9a18b298919d3a2

 

2.直方图均衡化

 直方图均衡化是通过灰度变换将一幅图象转换为另一幅具有均衡直方图,即在每个灰度级上都具有相同的象素点数的过程。

设灰度变换 s=f(r) 为斜率有限的非减连续可微函数,它将输入图象A(x,y)转换为输出图象B(x,y),输入图象的直方图为HA(r),输出图象的直方图为HB(s),则它们的关系可由如下过程导出:

直方图均衡化原理和编码实现(C/C++)

 


 

 

例如,下图是直方图均衡化后的飞机图片及其直方图,可见其直方图与原图的直方图相比是很均衡的,但必须说明的是,离散情况下不可能作到绝对的一致。

直方图均衡化原理和编码实现(C/C++)  直方图均衡化原理和编码实现(C/C++)

 

 

代码实现:

 

void HistNormolize(unsigned char **pImg, unsigned char **pNormImg,int width,int height)
{
 int hist[256];
 float  fpHist[256];
 float eqHistTemp[256];
 int eqHist[256];
 int size = height *width;
 int i ,j;

 memset(&hist,0x00,sizeof(int)*256);
 memset(&fpHist,0x00,sizeof(float)*256);
 memset(&eqHistTemp,0x00,sizeof(float)*256);

 for (i = 0;i < height; i++) //计算差分矩阵直方图
 {
  for (j = 0; j < width; j++)
  {
   unsigned char GrayIndex = pImg[i][j];
   hist[GrayIndex] ++ ;
  }
 }

 for (i = 0; i< 256; i++)   // 计算灰度分布密度
 {
  fpHist[i] = (float)hist[i] / (float)size;
 }
 for ( i = 1; i< 256; i++)   // 计算累计直方图分布
 {
  if (i == 0)
  {
   eqHistTemp[i] = fpHist[i];
  }
  else
  {
   eqHistTemp[i] = eqHistTemp[i-1] + fpHist[i];
  }
 }

 //累计分布取整,保存计算出来的灰度映射关系
 for (i = 0; i< 256; i++)
 {
  eqHist[i] = (int)(255.0 * eqHistTemp[i] + 0.5);
 }

 for (i = 0;i < height; i++) //进行灰度映射 均衡化
 {
  for (j = 0; j < width; j++)
  {
   unsigned char GrayIndex = pImg[i][j];
   pNormImg[i][j] = eqHist[GrayIndex];
  }
 }

}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值