随笔 - 632  文章 - 17  评论 - 54  阅读 - 93万

OpenCv绘制图像直方图

一、具体代码表示,ps:代码中有详细注释

复制代码
/**
 * 绘制直方图:直方图是变量分布的统计图形表示,它让我们能够理解数据的密度估计和概率分布。
 * 直方图通过将整个变量值范围划分为小的值范围,然后计算每个间隔中落入多少个值来创建
 * @param inputImagePath 绘制直方图的原图路径
 */
void showCalcHist(char *inputImagePath) {
    //加载原图
    Mat src = imread(inputImagePath);
    if (src.empty()) {
        cout << "图像数据不存在" << endl;
        return;
    }
    //将原图进行拆分,并存入向量集合中
    vector<Mat> bgr;
    //将输入图像划分为三个通道R、G、B
    split(src, bgr);
    //设置直方图有256个区间,因为图像的灰度值变化为0~255
    int numbers = 256;
    //定义变量范围,并定义三个矩阵来存储每个直方图
    float range[] = {0, 256};
    const float *histRange = {range};
    Mat b_hist, g_hist, r_hist;
    /*
     * calcHist用来计算图像直方图:
     * 参数详解:
        const Mat* images:输入图像
         int nimages:输入图像的个数
        const int* channels:需要统计直方图的第几通道
        InputArray mask:掩膜,,计算掩膜内的直方图  ...Mat()
        OutputArray hist:输出的直方图数组
        int dims:需要统计直方图通道的个数
        const int* histSize:指的是直方图分成多少个区间,就是 bin的个数
        const float** ranges: 统计像素值得区间
        bool uniform=true::是否对得到的直方图数组进行归一化处理
        bool accumulate=false:在多个图像时,是否累计计算像素值得个数
     */
    calcHist(&bgr[0], 1, 0, Mat(), b_hist, 1, &numbers, &histRange);
    calcHist(&bgr[1], 1, 0, Mat(), g_hist, 1, &numbers, &histRange);
    calcHist(&bgr[2], 1, 0, Mat(), r_hist, 1, &numbers, &histRange);
    //计算出每个通道的直方图后绘制直方图,并显示给用户
    int width = 512;
    int height = 320;
    //创建一个灰度图像
    Mat histImage(height, width, CV_8UC3, Scalar(20, 20, 20));
    //
    normalize(b_hist, b_hist, 0, height, NORM_MINMAX);
    normalize(g_hist, g_hist, 0, height, NORM_MINMAX);
    normalize(r_hist, r_hist, 0, height, NORM_MINMAX);

    int binStep = cvRound((float )width/(float )numbers);
    for(int i=0;i<numbers;i++){
        try {
            line(
                    histImage,
                    Point(binStep*(i-1),height- cvRound(b_hist.at<float>(i-1))),
                    Point(binStep*(i),height- cvRound(b_hist.at<float>(i))),
                    Scalar(255,0,0)
            );
            line(
                    histImage,
                    Point(binStep*(i-1),height- cvRound(g_hist.at<float>(i-1))),
                    Point(binStep*(i),height- cvRound(g_hist.at<float>(i))),
                    Scalar(0,255,0)
            );
            line(
                    histImage,
                    Point(binStep*(i-1),height- cvRound(r_hist.at<float>(i-1))),
                    Point(binStep*(i),height- cvRound(r_hist.at<float>(i))),
                    Scalar(0,0,255)
            );
        }catch (Exception exception){
            cout << exception.err <<endl;
        }


    }
    //展示原图
    imshow("src",src);
    //展示直方图
    imshow("histWindow",histImage);
    //销毁原始图像
    src.release();
    waitKey(0);
    //销毁原图和直方图的两个窗口
    destroyWindow("src");
    destroyWindow("histWindow");

}
复制代码

二、图片展示

 

posted on   飘杨......  阅读(439)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示