OpenCV 直方图统计函数 cv::calcHist算是彻底弄明白了

news2025/1/10 2:44:44

参数说明

void calcHist( const Mat* images, int nimages,
                          const int* channels, InputArray mask,
                          OutputArray hist, int dims, const int* histSize,
                          const float** ranges, bool uniform = true, bool accumulate = false );
  • images 图像数组。每个图像的大小要一致,depth要一致,即数据类型要一致,但通道数可以不一致。
  • nimages 图像数组的大小,即images数组的大小
  • channels 参与计算的各个通道的索引。由于各图像的通道数并不一定一致,并且此函数也不强制要求所有通道都参与计算,因此此参数用于指定要参与计算的图像的通道索引。索引值包含了图像标识,以及图像的通道标识。具体方法为:
    第一个图像的索引标识为 [0,  images[0].channels()), 
    第二个图像的索引标识为 [mages[0].channels(),  mages[0].channels()+mages[1].channels())
    之后以此类推。
    例如:
    图像mages[0]有三个通道,其通道索引为{0, 1, 2};
    图像mages[1] 有两个通道,其通过索引为 {3, 4};
    图像mages[2] 有三个通道,其通过索引为 {5, 6, 7}
  • mask 此函数支持对图像中指定区域进行直方图统计
  • hist 直方图统计结果
  • dims 直方图维度。使用最多的也就是1维、2维,更高维应该很少吧。本文后续再详细说明。
  • histSize 指定各个通道的的直方图中分类数。此函数的设计是,多个像素取值可以划分为同个分类,例如:像素灰度值取值范围是[0, 255],但不一定要分成256类,可以为了8类,就可以通过histSize 这个参数指定。
  • ranges 指定各个通道的像素灰度值的取值范围。也就是说,此函数的设计并不要求各个通道的像素灰度值取值范围一致。例如:可以第一个通道取值是[0, 255], 第二个通道取值是[0, 127]。
    此外,此参数地用于与uniform的取值有关。
    uniform取值为true时,表示将像素取值平均分配为 histSize[i]个区域(此处的i表示,参与计算的第i个通道),此时,ranges[i]数组的大小通道是2,即ranges[i][0] 表示像素值的最小值,ranges[i][1]表示像素取值的最大值。
    uniform取值为false时,表示不平均分配区间。此时,此函数就不知道如何划分区间了,就需要调用者指定。此时,ranges[i]数组的大小为区间个数加1,即histSize[i]+1。

一维颜色直方图

如果要统计一个RGB图像,三个通道的各自的直方图,需要将dims设置为1,并调用三次calcHist函数。

{
    READ_IMG_DEF_ERR_RET(img, "img1.jpg");

    cv::imshow("原始图像", img);


    int channels[1] = { 0 }; 
    int histSize[1] = { 256 };
    float range[2] = { 0, 256 };
    const float* ranges[1] = { range}; // 指定每个通道的取值范围

    // 计算B通道的颜色直方图
    cv::Mat bHist;
    cv::calcHist(&img, 1, channels, cv::Mat(), bHist, 1, histSize, ranges);
    PRINT_IMG_INFO(bHist);
    // 计算G通道的颜色直方图
    cv::Mat gHist;
    cv::calcHist(&img, 1, channels, cv::Mat(), gHist, 1, histSize, ranges);
    PRINT_IMG_INFO(gHist);
    // 计算R通道的颜色直方图
    cv::Mat rHist;
    cv::calcHist(&img, 1, channels, cv::Mat(), rHist, 1, histSize, ranges);
    PRINT_IMG_INFO(rHist);

    cv::Mat bHistImg  = ImgTools->buildHistImg(bHist, 600, 600, cv::Scalar(255, 0, 0));
    cv::imshow("颜色直方图 B", bHistImg);
    cv::Mat gHistImg  = ImgTools->buildHistImg(gHist, 600, 600, cv::Scalar(0, 255, 0));
    cv::imshow("颜色直方图 G", gHistImg);
    cv::Mat rHistImg  = ImgTools->buildHistImg(rHist, 600, 600, cv::Scalar(0, 0, 255));
    cv::imshow("颜色直方图 R", rHistImg);

    cv::waitKey(0);
}

二维颜色直方图

此时需要将dims参数设置为2。

{
    cv::Mat imgs[2];
    imgs[0] = (cv::Mat_<uchar>(2, 4) << 0, 1,  3,  3, 3,  5,  6, 7);
    imgs[1] = (cv::Mat_<uchar>(2, 4) << 8, 9, 10, 11, 11, 13, 14, 15);

    ImgTools->dumpImg(imgs[0], "imags[0]: ");
    ImgTools->dumpImg(imgs[1], "imags[1]: ");

    cv::Mat img;
    cv::merge(imgs, sizeof(imgs) / sizeof(imgs[0]), img);
    ImgTools->dumpImg(img, "imag: ");

    int channels[3] = { 0, 1  }; 
    
    int histSize[3] = { 8, 8 };  
    float rRange[2] = { 0, 8 };
    float gRange[2] = { 8, 16 };
    const float* ranges[2] = { rRange, gRange}; // 指定每个通道的取值范围

    cv::Mat hist;
    cv::calcHist(&img, 1, channels, cv::Mat(), hist, 2, histSize, ranges);
    ImgTools->dumpImg(hist, "hist info:");

}

运行结果如下图所示:

 在代码中,计算两个通道,通过参数histSize指定,每个通道都分成8个分区,因此可能有64种组合结果,因此二维直方图的大小为8*8的矩阵。

在图像中(3,10)这个组合的数据只有一个,对应的分区编号是(3,2),因此二维直方图中(3,2)位置的数据值为1,即上图中绿色标记的位置。
在图像中 (3, 11)这个组合的数据有两个, (3, 11)对应的分区编号是(3,3),因此上图中的红色标记的位置的统计值为2

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

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

相关文章

龙的画法图片

由龙老师画素描中国龙的方法,大概可以遵循以下步骤: 确定龙的姿态和比例:在纸上简单地画出龙的基本形状和姿态,包括身体的长度,颈部、腿和尾巴的位置和比例关系。 添加细节:在基本形状的基础上,开始添加一些细节,如龙的头部、眼睛、鼻子、嘴巴、爪子等。注意要保持姿态和比例…

来,花半小时我带你入门vue

半小时入门vue 前言&#xff08;&#xff01;important&#xff09;学习vue的前提什么是vue&#xff1f;vue的引入方式实例化一个对象和创建一个对象实例化一个vue对象模板语法1.插值表达式2.v-text和v-html指令3.v-bind指令4.v-on指令5.v-model指令6.v-if和v-show指令7.v-for指…

浅谈一下接口工具(jmeter、postman、swagger等)

一、接口都有哪些类型&#xff1f; 接口一般分为两种&#xff1a;1.程序内部的接口 2.系统对外的接口 系统对外的接口&#xff1a;比如你要从别的网站或服务器上获取资源或信息&#xff0c;别人肯定不会把 数据库共享给你&#xff0c;他只能给你提供一个他们写好的方法来获取…

MySQL中文乱码问题记录

概述 中文乱码是我们日常编程开发中经常会遇到的问题&#xff0c;包括&#xff1a; 浏览器&#xff08;页面&#xff09;显示乱码&#xff0c;参考记一次中文乱码排查解决流程Linux系统字体缺失导致中文乱码&#xff0c;参考Linux环境下Selenium截图乱码及字体安装及与字符集…

Excel突然弹出 请注意!您的文档的部分内容可能包含文档检测器无法删除的个人信息

环境&#xff1a; excel2016 Win10 专业版 问题描述&#xff1a; Excel突然弹出 请注意&#xff01;您的文档的部分内容可能包含文档检测器无法删除的个人信息 解决方案&#xff1a; 1.打开excel点击左上角的“文件”菜单项 2.依次选择&#xff1a;选项-》信任中心-》信…

(学习日记)2023.5.11

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

【小沐学Python】Python实现Web图表功能(ECharts.js,Flask+Vue)

文章目录 1、简介1.1 Vue1.2 Flask 2、Flask echarts.js Vue2.1 Vue2 (CDN) Vue-ECharts2.2 Vue3 (CDN) Vue-ECharts2.3 Vue3 (npm) Flask / nodejs 3、FAQ3.1 Fatal error in launcher: Unable to create process using "c:\users\tomcat\desktop\flask_english\adm…

【华为HCIP | 高级网络工程师】刷题日记(6)

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大二在校生 &#x1f43b;‍❄️个人主页&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;落798. &#x1f54a;️系列专栏&#xff1a;零基础学java ----- 重识c语言 ---- 计算机网络 &#x1f413;每日一…

机器学习工作流程

机器学习的定义机器学习的工作流程获取到的数据集的特性 1、什么是机器学习 机器学习是从数据中自动分析获得模型&#xff0c;并利用模型对未知数据进行预测。 2、机器学习工作流程 机器学习工作流程总结 1、获取数据2、数据基本处理3、特征工程4、机器学习&#xff08;模型…

Maven POM和Maven构建配置文件操作笔记

目录 我到现在还是没有太搞懂Maven的作用&#xff0c;我只是有一个模糊的概念就是它可以添加很多的依赖&#xff0c;这样会使项目搭建起来更加方便&#xff0c;你可以谈谈你的看法吗&#xff1f; Maven POM 父&#xff08;Super&#xff09;POM POM 标签大全详解 Maven 构建…

【云原生】Kubeadm部署k8s

【云原生】-- Kubeadm部署k8s 一、部署步骤二、部署kubernetes1、所有节点关闭防火墙 核心防护 iptables规则 swap交换2、修改主机名3、调整内核参数 三、安装Docker1、所有节点安装docker2、所有节点配置Kubernetes源3、所有节点安装kubeadm&#xff0c;kubelet和kubectl 四、…

【Java】抽象类与接口

文章目录 1.抽象类1.1抽象方法 2.接口3.抽象类和接口的区别3.1代码中区分&#xff1a;3.2设计层面区分 在面向对象编程中&#xff0c;抽象是非常重要的一个特征。在Java中可以通过抽象类或接口的形式实现这一特性。 1.抽象类 Java关键字 abstract对应抽象类的使用 1.1抽象方法…

【快速排序】

快速排序 递归法 1、快排 快速排序算法使基于分治策略的一个排序算法&#xff0c;其基本思想是&#xff0c;对于输入的子数组 nums[left : right] 按以下3个步骤排序&#xff1a; &#xff08;1&#xff09;分解&#xff1a;以 nums[left] 为基准元素将 nums[left : right] …

Wisej.NET 3.2 WiseJ Framework Crack

Web Development for Business Applications build ›› migrate ›› modernize ›› See the amazing things people are doing with Wisej.NET Customer storiesmadewithWisej.com Wisej 3.2 is released! read more ›› Wisej.NET Rapid .NET Web Development - 3.2 beta …

【深度学习】第一门课 神经网络和深度学习 Week 1 深度学习概论

文章目录 目录 目录 文章目录 1.1 欢迎来到深度学习 1. 为什么要学深度学习&#xff1f; 2. 我们将学习到哪些内容&#xff1f; 1.2 什么是神经网络&#xff1f; 引例 问题 题解 抽象 复杂化问题 建模 1.3 用神经网络进行监督学习 1. 概念辨析 2. 用神经网络进…

Hive 实战第一讲 hive基本介绍以及环境搭建

文章目录 1.Hive介绍1.1 hive 基本情况1.2 Hive架构原理1.3 Hive 安装1.4 元数据配置1.5 hive 服务部署1.6Hive常用交互命令1.6.1 Hive参数配置方式 1.Hive介绍 1.1 hive 基本情况 hive基于Hadoop的一个数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张表。 Hive是…

程序员必备的工具网站,大幅度提升你的工作效率

前言&#xff1a; 相信很多人不光是在编程的过程中&#xff0c;在平时的生活中&#xff0c;也经常会收藏一些有用的网站&#xff0c;方便使用的时候&#xff0c;靠这些网站来解决一些麻烦的事情。 我就把我收藏的一些经常用的工具网站分享给你们&#xff0c;你们也可以收藏起来…

web网络安全

在学习网络安全之前&#xff0c;必须要先知道一个组织——OWASP。 OWASP是一个开源的、非盈利的全球性安全组织&#xff0c;致力于应用软件的安全研究。我们基于该组织公布的技术文档来学习相关网络攻击原理和预防措施&#xff0c;web安全的核心是——永远不要相信用户传过来的…

OLED显示实验

实验内容 点亮OLED&#xff0c;并实现ASCII 字符的显示。 OLED简介 OLED&#xff0c;即有机发光二极管&#xff08;Organic Light-Emitting Diode&#xff09;&#xff0c;又称为有机电激光显示&#xff08;Organic Electroluminesence Display&#xff0c; OELD&#xff09…

Java10

Java10 &#xff08;一&#xff09;、配置文件&#xff08;二&#xff09;、多线程2.1 并发和并行2.2 多线程的实现方式2.3 常见成员方法2.3.1 线程的优先级2.3.2 守护线程&#xff08;备胎线程&#xff09;2.3.3 礼让线程和插入线程 2.4 线程生命周期2.4 线程安全问题2.5 锁2.…