当前位置:   article > 正文

c++实现直方图均衡化_c++代码,灰度图像灰度直方图和灰度图像均衡化

c++代码,灰度图像灰度直方图和灰度图像均衡化
直方图均衡化是一种用于图像增强的方法,通过调整图像的像素值分布,使得图像的对比度更好,细节更加显著。直方图均衡化的过程如下:
  1. 计算原始图像的灰度直方图,即统计图像中每个灰度级别的像素数量。
  2. 将灰度直方图归一化,将每个灰度级别出现的像素数量除以总像素数量,得到归一化后的直方图。
  3. 计算累积直方图,将归一化后的直方图进行累加操作,得到每个灰度级别对应的累积频率。
  4. 根据累积直方图调整原始图像的像素值。对于每个像素值v,将其映射到新的像素值v',计算公式为v' = (L - 1) * cumulative_hist(v),其中L为灰度级别的数量。
  5. 将调整后的像素值重新赋给原始图像的对应位置,完成图像均衡化。
直方图均衡化能够扩展图像的动态范围,使得图像中的像素值更均匀分布,从而提高图像的视觉效果和质量。
首先,我们选择一副较暗或者较量的图,对其进行直方图均衡化处理,首先我们先画一下下图的灰度直方图,可以看到图像整体亮度偏低,因此灰度级应该分布在较低的地方,没有充分利用到亮区的信息。

原图:直方图:

 

均衡化后的图像和直方图:

可以看到均衡化后的灰度分布就是在[0,255]上更加接近均匀分布,图像整体的对比度也增加。

  1. #include<opencv2/core.hpp>
  2. #include<opencv2/imgcodecs.hpp>
  3. #include<opencv2/highgui.hpp>
  4. #include<opencv2/imgproc.hpp>
  5. #include <iostream>
  6. using namespace cv;
  7. using namespace std;
  8. //@para gray:需要统计的图 Hist:用于存放统计数据
  9. void GetHist(Mat gray,Mat &Hist) //统计8Bit量化图像的灰度直方图
  10. {
  11. const int channels[1] = { 0 }; //通道索引
  12. float inRanges[2] = { 0,255 }; //像素范围
  13. const float* ranges[1] = {inRanges};//像素灰度级范围
  14. const int bins[1] = { 256 }; //直方图的维度
  15. calcHist(&gray, 1, channels,Mat(), Hist,1, bins, ranges);
  16. }
  17. void ShowHist(Mat &Hist)
  18. {
  19. //准备绘制直方图
  20. int hist_w = 512;
  21. int hist_h = 400;
  22. int width = 2;
  23. Mat histImage = Mat::zeros(hist_h,hist_w,CV_8UC3); //准备histImage为全黑背景色
  24. for (int i = 0; i < Hist.rows; i++)
  25. {
  26. rectangle(histImage,Point(width*(i),hist_h-1),Point(width*(i+1),hist_h-cvRound(Hist.at<float>(i)/100)),
  27. Scalar(255,255,255),-1);
  28. //cout << "像素值为" << i << "的个数:" << Hist.at<float>(i) << endl;
  29. }
  30. namedWindow("histImage", WINDOW_AUTOSIZE);
  31. imshow("histImage", histImage);
  32. //waitKey(0);
  33. }
  34. //获得
  35. void GetHistList(const Mat src,float *bin,int num)
  36. {
  37. //遍历所有的像素值
  38. for (int r=0;r<src.rows;r++)
  39. {
  40. for (int c=0;c<src.cols;c++)
  41. {
  42. int index = src.at<uchar>(r,c);
  43. bin[index]++; //bin为灰度级像素数的统计数组
  44. }
  45. }
  46. //归一化操作
  47. for (int i=0;i<num;i++)
  48. {
  49. bin[i]=bin[i]/src.rows/src.cols;
  50. }
  51. //累计操作
  52. for (int i=0;i<num;i++)
  53. {
  54. if (i == 0)
  55. {
  56. bin[i] = bin[i];
  57. continue;
  58. }
  59. bin[i] = bin[i] + bin[i - 1];
  60. }
  61. for (int i = 0; i < num; i++)
  62. {
  63. cout << bin[i] << endl;
  64. }
  65. }
  66. //
  67. /*直方图均衡化操作
  68. 参数: Mat src:原图
  69. float* bin:src灰度概率统计的累计和数组
  70. int num:bin数组的大小
  71. Mat &des:直方图均衡化后的图像
  72. */
  73. void MyHisteq(const Mat src,float *bin,int num, Mat& des)
  74. {
  75. //首先,先为des开辟src相同大小的空间
  76. des.create(src.rows,src.cols,CV_8UC1);
  77. //针对每个像素值计算直方图均衡化的结果
  78. for (int r=0;r<src.rows;r++)
  79. {
  80. for (int c=0;c<src.cols;c++)
  81. {
  82. int index=src.at<uchar>(r,c);
  83. des.at<uchar>(r, c) = int(255 * bin[index]);
  84. }
  85. }
  86. }
  87. int main(int argc,char *argv)
  88. {
  89. Mat src,gray,hist1; //hist用于统计gray的直方图
  90. src=imread("dark.jpg");
  91. cvtColor(src,gray,CV_BGR2GRAY);
  92. GetHist(gray,hist1);//获得直方图
  93. ShowHist(hist1);
  94. namedWindow("gray");
  95. imshow("gray",gray);
  96. //获得灰度级统计矩阵
  97. float bin[256] = {0};
  98. int num = sizeof(bin) / sizeof(bin[0]);
  99. GetHistList(gray,bin,num); //bin存放的是灰度值概率的累计和
  100. Mat my_hist,hist2; //my_hist用于存放直方图均衡化的图像
  101. MyHisteq(gray, bin, num, my_hist);
  102. namedWindow("my_hist");
  103. imshow("my_hist",my_hist);
  104. GetHist(my_hist, hist2);
  105. ShowHist(hist2);
  106. waitKey(0);
  107. return 0;
  108. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/78922
推荐阅读
相关标签
  

闽ICP备14008679号