opencv之直方图绘制及均衡化

直方图均衡化优势

增强图像对比度,使对比度较低的局部区域获得高对比度。当图像非常暗或者非常亮,并且背景和前景之间的差异非常小时,此方法非常有效,能够解决暴露过度或暴露不足的问题。

直方图均衡化缺陷

背景噪声增强、有用信息减少,同时在增加图像对比度时,直方图会发生变化和扩散。

代码

#include 
#include 
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 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(i - 1))),
            Point((i)*bin_w, hist_h - cvRound(b_hist.at(i))), Scalar(255, 0, 0), 1, LINE_AA);

        line(histImage, Point((i - 1) * bin_w, hist_h - cvRound(g_hist.at(i - 1))),
            Point((i)*bin_w, hist_h - cvRound(g_hist.at(i))), Scalar(0, 255, 0), 1, LINE_AA);

        line(histImage, Point((i - 1) * bin_w, hist_h - cvRound(r_hist.at(i - 1))),
            Point((i)*bin_w, hist_h - cvRound(r_hist.at(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 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;
}

结果

opencv之直方图绘制及均衡化_第1张图片
opencv之直方图绘制及均衡化_第2张图片

你可能感兴趣的:(opencv,opencv,计算机视觉,c++,人工智能)