(原)Opencv中直方图均衡和图像动态范围拉伸的代码

转载请注明出处:

 http://www.cnblogs.com/darkknightzh/p/5102032.html

 

参考网址:

http://blog.csdn.net/abcjennifer/article/details/7401921

 

实际上opencv中有自带的直方图均衡的程序。

  1 #include <opencv2/opencv.hpp>
  2 #include <opencv2/highgui/highgui.hpp>
  3 #include <opencv2/imgproc/imgproc.hpp>
  4 using namespace cv;
  5 
  6 /*!
  7 * \brief   图像直方图均衡
  8 *
  9 * \param[in]        srcImg          输入图像
 10 * \param[in,out]    dstImg          输出图像
 11 *
 12 * \return           0               处理成功
 13 *
 14 * \date 2016-1-5    10:03:33
 15 *
 16 */
 17 int HistEQ(Mat& dstImg, const Mat& srcImg)
 18 {
 19     assert(srcImg.type() == CV_8UC1);
 20 
 21     if (&srcImg != &dstImg)    // 当输入和输出相同时,对输出矩阵不需要重新分配空间
 22     {
 23         dstImg = Mat(srcImg.rows, srcImg.cols, CV_8UC1);
 24     }
 25 
 26     double p[256] = { 0 }, num[256] = {0};
 27 
 28     //计算直方图
 29     for (auto i = 0; i < srcImg.rows; i++)
 30     {
 31         for (auto j = 0; j < srcImg.cols; j++)
 32         {
 33             uchar val = srcImg.at<uchar>(i, j);
 34             num[val]++;
 35         }
 36     }
 37 
 38     //计算概率分布
 39     for (auto i = 0; i < 256; i++)
 40     {
 41         p[i] = num[i] / (srcImg.rows * srcImg.cols);
 42     }
 43 
 44     //计算累计概率分布
 45     for (auto i = 1; i < 256; i++)
 46     {
 47         p[i] += p[i-1];
 48     }
 49 
 50     // 直方图变换
 51     for (auto i = 0; i < srcImg.rows; i++)
 52     {
 53         for (auto j = 0; j < srcImg.cols; j++)
 54         {
 55             uchar val = srcImg.at<uchar>(i, j);
 56             dstImg.at<uchar>(i, j) = static_cast<uchar>(p[val] * 255 + 0.5);
 57         }
 58     }
 59 
 60     return 0;
 61 }
 62 
 63 
 64 /*!
 65 * \brief   图像动态范围拉伸到[0, 255]
 66 *
 67 * \param[in]        srcImg          输入图像
 68 * \param[in,out]    dstImg          输出图像
 69 *
 70 * \return           0               处理成功
 71 *
 72 * \date 2016-1-5    10:03:33
 73 *
 74 */
 75 int DynamicStretch(Mat& dstImg, const Mat& srcImg)
 76 {
 77     assert(srcImg.type() == CV_8UC1);
 78     if (&srcImg != &dstImg)    // 当输入和输出相同时,对输出矩阵不需要重新分配空间
 79     {
 80         dstImg = Mat(srcImg.rows, srcImg.cols, CV_8UC1);
 81     }
 82     
 83     double maxVal = -std::numeric_limits<double>::max();
 84     double minVal = 0;
 85 //    int minIdx[2] = { 0 }, maxIdx[2] = { 0 }; // minMaxIdx函数返回x,y位置,故此处需要声明的数组大小为2
 86 
 87     minMaxIdx(srcImg, &minVal, &maxVal/*, minIdx, maxIdx*/);  // 寻找图像的最大最小值
 88 
 89     for (auto i = 0; i < srcImg.rows; i++)
 90     {
 91         for (auto j = 0; j < srcImg.cols; j++)
 92         {
 93             uchar val = srcImg.at<uchar>(i, j);
 94             dstImg.at<uchar>(i, j) = static_cast<uchar>(255 * (val - minVal) * 1.0 / (maxVal - minVal));
 95         }
 96     }
 97 
 98     return 0;
 99 }
100 
101 
102 /// \brief   主程序
103 int _tmain(int argc, _TCHAR* argv[])
104 {
105 
106     Mat img = imread("E:\\01.jpg", 0);
107     imshow("img", img);
108 
109     Mat imgEQ;
110     equalizeHist(img, imgEQ);  // opencv自带的直方图均衡的程序
111     imshow("imgEQ", imgEQ);
112 
113     Mat imgEQ2;
114     HistEQ(imgEQ2, img);       // 调用上面直方图均衡的函数HistEQ
115     imshow("imgEQ2", imgEQ2);
116 
117     Mat imgStretch;
118     DynamicStretch(imgStretch, img);  // 调用上面动态范围拉伸的函数HistEQ
119     imshow("imgStretch", imgStretch);
120 
121     waitKey(0);
122 
123     return 0;
124 }

 

posted on 2016-01-05 13:27  darkknightzh  阅读(3156)  评论(0编辑  收藏  举报

导航