参考:http://blog.csdn.net/abcjennifer/article/details/7428737
原理:将RGB空间转换为YUV(YCrCb)空间,对Y分量进行直方图均衡,再转换成RGB空间。转换成RGB空间主要为了方便用imshow显示,imshow好像无法直接正常显示YUV格式的图像(?待考)
代码:
#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <iostream> using namespace cv; using namespace std; /** * Histogram equalization */ Mat& MyHistEqual(Mat& I); /** * @function main */ int main( int argc, char** argv ) { // load image char* imageName = "images/curious.jpg"; Mat image; image = imread(imageName,1); if(!image.data) { cout << "No image data" << endl; return -1; } // show image namedWindow("image", CV_WINDOW_AUTOSIZE); imshow("image", image); Mat dst(image.rows, image.cols, image.type(), Scalar(0,0,0)); cvtColor( image, dst, CV_BGR2YCrCb ); MyHistEqual(dst); cvtColor( dst, image, CV_YCrCb2BGR ); namedWindow("color_histequal_image", CV_WINDOW_AUTOSIZE); imshow("color_histequal_image", image); //imwrite("color_histequal_image.jpg", image); waitKey(0); return 0; } Mat& MyHistEqual(Mat& I) { CV_Assert(I.data); // accept only char type matrices CV_Assert(I.depth() != sizeof(uchar)); const int channels = I.channels(); switch(channels) { case 1: { int Hist[256]; memset(Hist, 0, sizeof(Hist)); // form image histogramp MatIterator_<uchar> it, end; for( it = I.begin<uchar>(), end = I.end<uchar>(); it != end; it++ ) Hist[(*it)] ++; // form cumulative histograme for( int i = 1; i < 256; i++ ) Hist[i] += Hist[i-1]; // histogram equalization int nRows = I.rows; int nCols = I.cols; for( it = I.begin<uchar>(), end = I.end<uchar>(); it != end; it++ ) *it = (uchar)( 255 * Hist[(*it)] / (nRows * nCols) ); break; } case 3: // only equalize first color component, for YUV format { int Hist[256]; memset(Hist, 0, sizeof(Hist)); // form image histogramp MatIterator_<Vec3b> it, end; for( it = I.begin<Vec3b>(), end = I.end<Vec3b>(); it != end; it++ ) { Hist[(*it)[0]] ++; } // form cumulative histograme for( int i = 1; i < 256; i++ ) Hist[i] += Hist[i-1]; // histogram equalization int nRows = I.rows; int nCols = I.cols; for( it = I.begin<Vec3b>(), end = I.end<Vec3b>(); it != end; it++ ) (*it)[0] = (uchar)( 255 * Hist[(*it)[0]] / (nRows * nCols) ); } } return I; }
结果: