直方图均衡化优势:
增强图像对比度,使对比度较低的局部区域获得高对比度。当图像非常暗或者非常亮,并且背景和前景之间的差异非常小时,此方法非常有效,能够解决暴露过度或暴露不足的问题。
直方图均衡化缺陷:
背景噪声增强、有用信息减少,同时在增加图像对比度时,直方图会发生变化和扩散。
代码:
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
class QuickDemo
{
public:
    void hist_cal_equalize(Mat &image);
    Mat norm(Mat &image);
};
Mat QuickDemo::norm(Mat &image)
{
    vector<Mat> bgr_planes;
    // 将三通道图像划分成单通道图像
    split(image, bgr_planes);
    int histSize = 256;
    float range[] = { 0, 256 };
    const float *histRanges = { range };
    Mat b_hist, g_hist, r_hist;
    // 统计单通道图像直方图
    calcHist(&bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRanges, true, false);
    calcHist(&bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRanges, true, false);
    calcHist(&bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRanges, true, false);
    
    // 直方图高和宽
    int hist_h = 400;
    int hist_w = 512;
    int bin_w = hist_w / histSize;
    Mat histImage(hist_w, hist_h, CV_8UC3, Scalar(0, 0, 0));
    normalize(b_hist, b_hist, 0, hist_h, NORM_MINMAX, -1, Mat());  // 归一化到(0, hist_h)
    normalize(g_hist, g_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
    normalize(r_hist, r_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
    
    // 绘制直方图
    for (int i = 1; i < histSize; i++)
    {
        line(histImage, Point((i - 1) * bin_w, hist_h - cvRound(b_hist.at<float>(i - 1))),
            Point((i)*bin_w, hist_h - cvRound(b_hist.at<float>(i))), Scalar(255, 0, 0), 1, LINE_AA);
        line(histImage, Point((i - 1) * bin_w, hist_h - cvRound(g_hist.at<float>(i - 1))),
            Point((i)*bin_w, hist_h - cvRound(g_hist.at<float>(i))), Scalar(0, 255, 0), 1, LINE_AA);
        line(histImage, Point((i - 1) * bin_w, hist_h - cvRound(r_hist.at<float>(i - 1))),
            Point((i)*bin_w, hist_h - cvRound(r_hist.at<float>(i))), Scalar(0, 0, 255), 1, LINE_AA);
    }
    return histImage;
}
void QuickDemo::hist_cal_equalize(Mat &image)
{
    imshow("input", image);
    Mat hist_src, hist_dst;
    hist_src = norm(image);
    imshow("hist_src", hist_src);
    Mat img;
    image.copyTo(img);
    cvtColor(img, img, COLOR_BGR2YCrCb);
    vector<Mat> channel;
    split(img, channel);
    // 直方图均衡化,该函数只能处理单通道图像
    equalizeHist(channel[0], channel[0]);
    merge(channel, img);
    cvtColor(img, img, COLOR_YCrCb2BGR);
    imshow("output", img);
    hist_dst = norm(img);
    imshow("hist_dst", hist_dst);
}
int main()
{
    Mat image = imread("D:\\c++_opencv\\images\\0--Parade_0_Parade_marchingband_1_20.jpg", IMREAD_ANYCOLOR);
    QuickDemo qd;
    qd.hist_cal_equalize(image);
    waitKey(0);
    destroyAllWindows();
    return 0;
}结果:
 
    
    
    
   


















