实战OpenCV之直方图

news2024/9/23 11:33:02

基础入门

        直方图是对数据分布情况的图形表示,特别适用于图像处理领域。在图像处理中,直方图通常用于表示图像中像素值的分布情况。直方图由一系列矩形条(也被称为bin)组成,每个矩形条的高度表示某个像素值(或像素值范围)在图像中出现的频次。直方图的横轴(X轴)表示像素值的范围,通常对于8位灰度图像,其范围为0-255。直方图的纵轴(Y轴)表示在图像中每个像素值(或像素值范围)出现的频次。

        在OpenCV中,计算直方图使用cv::calcHist函数,其函数原型如下。

void cv::calcHist(const Mat* images, int nimages, const int* channels, 
    const Mat& mask, OutputArray hist, int dims, const int* histSize, 
    const float** ranges, bool accumulate=false);

        各个参数的含义如下。

        images:输入图像或图像集合的指针数组。images指向一个图像矩阵数组,nimages指定数组的长度,即要处理的图像数量。通常,当处理单个图像时,会传递一个包含单个图像地址的指针。

        nimages:输入图像的数量,表示images数组中图像的个数。

        channels:一个整数数组,指定了要从每个图像中使用的通道的索引。比如:如果处理的是一个三通道的BGR图像,并且只想计算蓝色通道的直方图,则应传递{0}。如果想计算所有通道的联合直方图,则可以传递{0, 1, 2}。

        mask: 可选的掩码图像,它定义了一个感兴趣的区域,只有这个区域内的像素才会被用于计算直方图。如果不需要掩码,可以传递一个空的cv::Mat()。

        hist:输出的直方图,它是一个多维数据的数组,其维度取决于dims和histSize参数。这个输出直方图需要事先创建好,或使用智能指自动管理内存。

        dims:直方图的维度。对于单通道图像,通常是1;对于多通道联合直方图,这个值会更高。

        histSize:指定每一维直方图的bin(桶)数量的数组。对于单通道8位图像,通常使用{256}来表示从0到255的每个灰度级都有一个bin。

        ranges:指定每个维度的值范围的数组的指针。通常情况下,对于单通道8位图像,每个维度的范围是{0, 256},意味着从0到255的像素值范围。数组中的每个元素都是一个包含两个元素(起始值和结束值)的数组。

        accumulate:如果设置为true,则当前计算的直方图会被累积到hist中已有的值上。默认值为false,意味着每次调用都会重新计算直方图,而不保留之前的结果。

实战解析

        在下面的实战代码中,我们首先读取一张图像,并转换为灰度图像img。然后,计算该图像的灰度直方图hist。其中histSize设为256,意味着将灰度级分为256个区间。接下来,我们使用cv::normalize函数对其进行归一化处理,以确保直方图的高度总和为1,便于可视化展示。

        最后,我们创建一个新的图像histImage,用于绘制直方图。通过循环遍历每个bin,根据每个bin的高度在histImage上绘制相应的矩形条,形成可视化的直方图。直方图的背景色为白色,矩形条的颜色为蓝色。

#include <opencv2/opencv.hpp>
using namespace cv;

#include <iostream>
using namespace std;

int main()
{
    Mat img = imread("OpenCV.png", IMREAD_GRAYSCALE);
    if(img.empty())
    {
        cout << "Can not open or find the image" << endl;
        return -1;
    }

    // 计算灰度直方图
    int channels[] = {0};
    int histSize = 256;
    float range[] = {0, 256};
    const float* histRange = {range};
    bool uniform = true;
    bool accumulate = false;
    Mat hist;
    calcHist(&img, 1, channels, Mat(), hist, 1, &histSize, &histRange, uniform, accumulate);

    // 对直方图进行归一化
    normalize(hist, hist, 0, 1, NORM_MINMAX, -1, Mat());

    // 绘制直方图
    int hist_w = 512;
    int hist_h = 400;
    int bin_w = cvRound((double)hist_w / histSize);
    Mat histImage(hist_h, hist_w, CV_8UC3, Scalar(255, 255, 255));
    for(int i = 1; i < histSize; i++)
    {
        rectangle(histImage, Point(bin_w*(i-1), hist_h - cvRound(hist.at<float>(i-1)*hist_h)),
            Point(bin_w*(i), hist_h), Scalar(255, 0, 0), -1);
    }

    // 显示原图和直方图
    imshow("Original Image", img);
    imshow("Histogram", histImage);

    waitKey(0);
    destroyAllWindows();
    return 0;
}

        执行上面的代码,运行效果可参考下图。

直方图比较

        比较两个直方图的相似度是通过cv::compareHist函数实现的,常用于图像检索、对象识别等场景,该函数的原型如下。

double cv::compareHist(InputArray H1, InputArray H2, int method);

        各个参数的含义如下。

        H1:第一个直方图。

        H2:第二个直方图,需要与H1有相同的尺寸和类型。

        method:指定用于比较直方图的方法,被定义为枚举类型cv::HistCompMethods,常用的比较方法如下。

          (1)cv::HISTCMP_CORREL:相关性方法,计算两个直方图之间的皮尔逊相关系数。此时,函数返回值表示两个直方图之间的皮尔逊相关系数,范围从[-1, 1]。值接近1表示两个直方图非常相似(高度相关),值接近-1表示两者几乎完全负相关,而接近0则表示没有线性关系。

          (2)cv::HISTCMP_INTERSECT:交集方法,计算两直方图的重叠部分。此时,函数返回值的范围是[0, 1]。值越接近1表示直方图越相似,值越接近0表示差异越大。

          (3)cv::HISTCMP_BHATTACHARYYA:巴氏距离,计算两直方图的巴塔查里亚距离。此时,函数返回值用于衡量两个直方图的相似度。这是一种基于概率密度函数的测度,值越小表示直方图越相似。最大值为1,表示完全不相似。

        在下面的实战代码中,我们首先读取两张灰度图像img1和img2。然后,分别计算每张图像的灰度直方图,并使用cv::normalize函数对直方图进行了归一化处理。接下来,我们使用cv::compareHist函数比较这两个直方图。最后,我们输出了比较结果,展示了两幅图像直方图的相似度。

#include <opencv2/opencv.hpp>
using namespace cv;

#include <iostream>
using namespace std;

int main()
{
    Mat img1 = imread("OpenCV.png", IMREAD_GRAYSCALE);
    Mat img2 = imread("C++.png", IMREAD_GRAYSCALE);
    if(img1.empty() || img2.empty())
    {
        cout << "Can not open or find the image" << endl;
        return -1;
    }

    // 计算两幅图像的直方图
    int histSize = 256;
    float range[] = {0, 256};
    const float* histRange = {range};
    bool uniform = true;
    bool accumulate = false;
    Mat hist1;
    Mat hist2;
    calcHist(&img1, 1, 0, Mat(), hist1, 1, &histSize, &histRange, uniform, accumulate);
    calcHist(&img2, 1, 0, Mat(), hist2, 1, &histSize, &histRange, uniform, accumulate);

    // 归一化直方图
    normalize(hist1, hist1, 0, 1, NORM_MINMAX, -1, Mat());
    normalize(hist2, hist2, 0, 1, NORM_MINMAX, -1, Mat());

    // 比较直方图
    double result = compareHist(hist1, hist2, HISTCMP_CORREL);
    // 输出:0.953461
    cout << result << endl;

    waitKey(0);
    destroyAllWindows();
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2157425.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3.6 第四行之__ipipe_init_proc()

点击查看系列文章 》 Interrupt Pipeline系列文章大纲-CSDN博客 原创不易&#xff0c;需要大家多多鼓励&#xff01;您的关注、点赞、收藏就是我的创作动力&#xff01; 3.6 第四行之__ipipe_init_proc() __ipipe_init_proc()并不是直接在start_kernel中调用&#xff0c;它的…

JavaScript高级——事件循环模型

1、 2、所有代码分类 ① 初始化执行代码&#xff08;同步代码&#xff09;&#xff1a;包含绑定 dom 事件监听&#xff0c;设置定时器&#xff0c;发送 ajax 请求的代码 ② 回调执行代码&#xff08;异步代码&#xff09;&#xff1a;处理回调逻辑 3、js 引擎执行代码的基本流…

【Linux篇】网络编程基础(笔记)

目录 一、服务器模型 1. C/S 模型 2. P2P模型 二、服务器编程框架 1. I/O处理单元 2. 逻辑单元 3. 网络存储单元 4. 请求队列 三、网络编程基础API 1. socket 地址处理 API &#xff08;1&#xff09;主机字节序和网络字节序 &#xff08;2&#xff09;通用socket地…

论文阅读:A Generalization of Transformer Networks to Graphs

论文阅读&#xff1a;A Generalization of Transformer Networks to Graphs 论文地址1 摘要2 贡献Graph TransformerOn Graph Sparsity&#xff08;图稀疏&#xff09;On Positional Encodings&#xff08;位置编码&#xff09;3 Graph Transformer Architecture&#xff08;架…

GPT实现联网,NextChat插件的配置说明

简介 NextChat开源版本已支持插件调用。 不过&#xff0c;插件的配置略复杂&#xff0c;为了降低普通用户的配置难度&#xff0c;本文基于中转API做详细配置说明&#xff0c;后续如果有新增插件&#xff0c;本文也将同步更新配置说明。 在配置具体插件之前&#xff0c;你需要…

Spring后端直接用枚举类接收参数,自定义通用枚举类反序列化器

在使用枚举类做参数时&#xff0c;一般会让前端传数字&#xff0c;后端将数字转为枚举类&#xff0c;当枚举类很多时&#xff0c;很可能不知道这个code该对应哪个枚举类。能不能后端直接使用枚举类接收参数呢&#xff0c;可以&#xff0c;但是受限。 Spring反序列默认使用的是J…

The NCCoE’s Automation of the CMVP

Earlier today at the ICMC24, we heard from a panel about the US National Cybersecurity Center of Excellence’s (NCCoE) work on the Automated Cryptographic Module Validation Program (ACMVP), which intends to tackle the troublingly long queue times we’ve se…

Apifox 「定时任务」操作指南,解锁自动化测试的新利器

定时任务是按照预设时间自动执行的任务&#xff0c;它可以有效解决一些常见问题&#xff0c;比如频繁执行的回归测试和大规模的接口测试&#xff0c;这些任务需要在固定时间点或间隔周期内自动运行&#xff0c;以确保软件的持续集成和持续交付过程中的稳定性和可靠性。通过使用…

实操学习——个人资料的录入、修改、密码的修改

实操学习——个人资料的录入、修改、密码的修改 一、个人资料的录入和修改知识补充&#xff1a;装饰器二、密码的修改知识补充&#xff1a;docker的关闭与启动 一、个人资料的录入和修改 在users的app下创建一个用户详情表 from django.contrib.auth.models import User from…

C/C++逆向:switch语句逆向分析

在逆向分析中&#xff0c;switch语句会被编译器转化为不同的底层实现方式&#xff0c;这取决于编译器优化和具体的场景。常见的实现方式包括以下几种&#xff1a; ①顺序判断&#xff08;if-else链&#xff09;&#xff1a; 编译器将switch语句转化为一系列的if-else语句。这…

【第十四章:Sentosa_DSML社区版-机器学习时间序列】

目录 【第十四章&#xff1a;Sentosa_DSML社区版-机器学习时间序列】 14.1 ARIMAX 14.2 ARIMA 14.3 HoltWinters 14.4 一次指数平滑预测 14.5 二次指数平滑预测 【第十四章&#xff1a;Sentosa_DSML社区版-机器学习时间序列】 14.1 ARIMAX 1.算子介绍 考虑其他序列对一…

Flutter鸿蒙化(windows)

Flutter鸿蒙化&#xff08;windows&#xff09; 参考资料Window配置Flutter的鸿蒙化环境下载配置环境变量HarmonyOS的环境变量配置配置Flutter的环境变量Flutter doctor -v 检测的问题flutter_flutter仓库地址的警告问题Fliutter doctor –v 报错[!] Android Studio (version 2…

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-18

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-18 1. The Application of Large Language Models in Primary Healthcare Services and the Challenges W YAN, J HU, H ZENG, M LIU, W LIANG - Chinese General Practice, 2024 人工智能大语言模型在基层医疗…

软媒市场新探索:软文媒体自助发布,开启自助发稿新篇章

在繁华喧嚣的软媒市场中,每一个声音都在竭力呼喊,每一个品牌都在奋力展现。而软文,作为一种温柔而坚韧的营销力量,正逐渐崭露头角。特别是软文媒体自助发布平台的出现,更是为企业提供了一个全新的、高效的自助发稿渠道。 软媒市场自助发布平台,正如其名,是一个让企业能够自主发…

离职员工客户如何管理?解锁2024企业微信新功能

公司里员工来来去去很正常&#xff0c;但每次有人走&#xff0c;老板们都会头疼&#xff0c;因为客户信息得有人接着管。客户对公司来说太重要了&#xff0c;不能丢。2024年&#xff0c;企业微信出了个新招&#xff0c;就是员工离职后&#xff0c;客户信息可以轻松转给新来的员…

JVM的基本概念

目录 一、JVM的内存划分 二、JVM的类加载过程 三、JVM的垃圾回收机制&#xff08;GC&#xff09; 四、分代回收 一、JVM的内存划分 一个运行起来的Java进程&#xff0c;就是一个Java虚拟机&#xff0c;就需要从操作系统中申请一大块内存。申请的内存会划分为不同的区域&…

Maven笔记(一):基础使用【记录】

Maven笔记&#xff08;一&#xff09;-基础使用 Maven是专门用于管理和构建Java项目的工具&#xff0c;它的主要功能有&#xff1a; 提供了一套标准化的项目结构 Maven提供了一套标准化的项目结构&#xff0c;所有IDE(eclipse、myeclipse、IntelliJ IDEA 等 项目开发工具) 使…

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-17

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-17 1. Large Language Models in Biomedical and Health Informatics: A Review with Bibliometric Analysis H Yu, L Fan, L Li, J Zhou, Z Ma, L Xian, W Hua, S He… - Journal of Healthcare …, 2024 生物…

HarmonyOS应用开发(组件库)--组件模块化开发、工具包、设计模式(持续更新)

致力于&#xff0c;UI开发拿来即用&#xff0c;提高开发效率 正则表达式...手机号校验...邮箱校验 文件判断文件是否存在 网络下载下载图片从沙箱中图片转为Base64格式从资源文件中读取图片转Base64 组件输入框...矩形输入框...输入框堆叠效果&#xff08;用于登录使用&#xf…

【自动驾驶】决策规划算法(二)参考线模块Ⅰ| 平滑算法与二次规划

写在前面&#xff1a; &#x1f31f; 欢迎光临 清流君 的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落。&#x1f4dd; 个人主页&#xff1a;清流君_CSDN博客&#xff0c;期待与您一同探索 移动机器人 领域的无限可能。 &#x1f50d; 本文系 清流君 原创之作&…