轉載請注明出處:
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 }