【OpenCV • c++】直方图计算

2023-11-15

一、什么是直方图

  直方图广泛应用于很多计算机视觉处理当中。通过标记帧与帧之间显著的边缘和颜色的变化,可以检测视频中的场景变化。在每个兴趣点设置一个有相似特征的直方图所构成的“标签”,可以用来标记各种不同的事情,比如图像的色彩分布,物体边缘梯度模板等等。是计算机视觉中最经典的工具之一。
  简单来说直方图就是对数据进行统计的一种方法,它将统计值组织到一系列事先定义好的bin中。bin中的数值是从数据中计算出的特征的统计量,这些数据可以是梯度、方向、色彩以及其他任何特征。直方图获取的是数据分布的统计图,通常情况下,直方图的维度要低于原始数据。由于原始数据可以表示任何事情,直方图就可以很好的表示图像的特征。

二、直方图的相关函数

1、计算直方图 calcHist()

  函数cv:calcHist()可以计算一个或多个数组的直方图。

void cv::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 
	) 	

  其中,第一个参数表示输入的数组或数组集,它们需要相同的深度和相同的尺寸。第二个参数表示输入数组的个数,也就是第一个参数中有几个原数组。第三个参数表示需要统计的通道索引。第四个参数表示可选的操作掩码,如果不为空,那么必须为8位,并且与images[i]有同样大小的尺寸,这里的非零掩码元素用于标记出统计直方图的数组元素数据。第五个参数表示输出的目标直方图,是一个二维数组。第六个参数表示需要计算的直方图维度,必须是正数。第七个参数表示存放每个维度的直方图尺寸的数组。第八个参数表示每一维数值的取值范围,第九个参数表示直方图是否均匀的标识符,默认为true。第十个参数表示累计标识符,有默认值false。若为true,直方图在配置阶段不会被清零。此功能主要是允许从多个阵列中计算单个直方图,或者用于在特定的时间更新直方图。

2、找寻最值 minMaxLoc()

  函数minMaxLoc() 查找最小和最大元素值及其位置。在整个数组中搜索极值,如果掩码不是空数组,则在指定的数组区域中搜索极值。

void cv::minMaxLoc 	( 	InputArray  	src,
		double *  	minVal,
		double *  	maxVal = 0,
		Point *  	minLoc = 0,
		Point *  	maxLoc = 0,
		InputArray  	mask = noArray() 
	) 	

  其中第一个参数表示输入的单通道列阵。第二个参数表示返回最小值的指针,若无须返回则为NULL。第三个参数表示返回的最大值的指针,若无须返回则为NULL。第四个参数表示返回最小位置的指针若无须返回则为NULL。第五个参数表示返回最大位置的指针若无须返回则为NULL。

三、程序演示

1、色调 —— 饱和度直方图

  下面我们来说明一下如何计算彩色图像的色调 —— 饱和度直方图。

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

int main()
{
	// 读取图像并创建一个Mat对象来存储图像数据
	Mat src, hsv;
	src = imread("C://Users//86173//Desktop//c.png");

	// 检查图像是否成功加载
	if (!src.data)
		return -1;

	// 将图像从BGR颜色空间转换为HSV颜色空间
	cvtColor(src, hsv, COLOR_BGR2HSV);

	// 定义直方图的参数
	int hbins = 30, sbins = 32;
	int histSize[] = { hbins, sbins };
	float hranges[] = { 0, 180 };
	float sranges[] = { 0, 256 };
	const float* ranges[] = { hranges, sranges };

	// 创建一个用于存储直方图的Mat对象
	MatND hist;

	// 指定通道
	int channels[] = { 0, 1 };

	// 计算直方图
	calcHist(&hsv, 1, channels, Mat(), hist, 2, histSize, ranges, true, false);

	// 寻找直方图的最大值
	double maxVal = 0;
	minMaxLoc(hist, 0, &maxVal, 0, 0);

	// 定义绘制直方图的参数
	int scale = 10;
	Mat histImg = Mat::zeros(sbins * scale, hbins * 10, CV_8UC3);

	// 绘制直方图
	for (int h = 0; h < hbins; h++)
	{
		for (int s = 0; s < sbins; s++)
		{
			float binVal = hist.at<float>(h, s);
			int intensity = cvRound(binVal * 255 / maxVal);
			rectangle(histImg, Point(h * scale, s * scale), Point((h + 1) * scale - 1, (s + 1) * scale - 1), Scalar::all(intensity), -1);
		}
	}

	// 创建并显示源图像窗口
	namedWindow("Source", 1);
	imshow("Source", src);

	// 创建并显示H-S直方图窗口
	namedWindow("H-S Histogram", 1);
	imshow("H-S Histogram", histImg);

	waitKey();
}

在这里插入图片描述

2、一维直方图

  下面我们来介绍一下如何计算绘制图像一维直方图。

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/utils/logger.hpp>

using namespace cv;
using namespace std;

int main()
{
    // 读取图像
    Mat srcImage = imread("C://Users//86173//Desktop//c.png");
    if (!srcImage.data)
    {
        printf("fail to load image!\n");
        return 0;
    }
    // 显示原始图像
    imshow("【原始图】", srcImage);

    // 计算直方图
    MatND dstHist;
    int dims = 1;
    float hranges[] = { 0, 255 };
    const float* ranges[] = { hranges };
    int size = 256;
    int channels = 0;

    calcHist(&srcImage, 1, &channels, Mat(), dstHist, dims, &size, ranges, true, false);

    // 创建用于显示直方图的图像
    int scale = 1;
    Mat dstImage(size * scale, size, CV_8U, Scalar(0));

    // 获取直方图的最小值和最大值
    double minValue = 0;
    double maxValue = 0;
    minMaxLoc(dstHist, &minValue, &maxValue, 0, 0);

    // 绘制直方图
    int hpt = saturate_cast<int>(0.9 * size);
    for (int i = 0; i < 256; i++)
    {
        float binValue = dstHist.at<float>(i);
        int realValue = saturate_cast<int>(binValue * hpt / maxValue);
        rectangle(dstImage, Point(i * scale, size - 1), Point((i + 1) * scale - 1, size - realValue), Scalar(255));
    }
    // 显示一维直方图
    imshow("一维直方图", dstImage);

    waitKey(0);
    return 0;
}

在这里插入图片描述

3、RGB 三色直方图

  下面我们来介绍一下如何绘制图像的 RGB 三色直方图。

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/utils/logger.hpp>

using namespace cv;
using namespace std;

int main()
{
    // 读取图像
    Mat srcImage = imread("C://Users//86173//Desktop//c.png");
    if (!srcImage.data)
    {
        printf("fail to load image!\n");
        return 0;
    }
    imshow("【原始图】", srcImage);

    int bins = 256;
    int hist_size[] = { bins };
    float range[] = { 0, 256 };
    const float* ranges[] = { range };
    MatND redHist, grayHist, blueHist;

    // 计算红色分量的直方图
    int channels_r[] = { 0 };
    calcHist(&srcImage, 1, channels_r, Mat(), redHist, 1, hist_size, ranges, true, false);

    // 计算绿色分量的直方图
    int channels_g[] = { 1 };
    calcHist(&srcImage, 1, channels_g, Mat(), grayHist, 1, hist_size, ranges, true, false);

    // 计算蓝色分量的直方图
    int channels_b[] = { 2 };
    calcHist(&srcImage, 1, channels_b, Mat(), blueHist, 1, hist_size, ranges, true, false);

    // 绘制三色直方图
    // 参数准备
    double maxValue_red, maxValue_green, maxValue_blue;
    minMaxLoc(redHist, 0, &maxValue_red, 0, 0);
    minMaxLoc(grayHist, 0, &maxValue_green, 0, 0);
    minMaxLoc(blueHist, 0, &maxValue_blue, 0, 0);

    int scale = 1;
    int histHeight = 256;
    Mat histImage = Mat::zeros(histHeight, bins * 3, CV_8UC3);

    // 正式绘制
    for (int i = 0; i < bins; i++)
    {
        // 参数准备
        float binValue_red = redHist.at<float>(i);
        float binValue_green = grayHist.at<float>(i);
        float binValue_blue = blueHist.at<float>(i);
        int intensity_red = cvRound(binValue_red * histHeight / maxValue_red);    // 要绘制的高度
        int intensity_green = cvRound(binValue_green * histHeight / maxValue_green);    // 要绘制的高度
        int intensity_blue = cvRound(binValue_blue * histHeight / maxValue_blue);    // 要绘制的高度

        // 绘制红色分量的直方图
        rectangle(histImage, Point(i * scale, histHeight - 1), Point((i + 1) * scale - 1, histHeight - intensity_red), Scalar(255, 0, 0));
        // 绘制绿色分量的直方图
        rectangle(histImage, Point((i + bins) * scale, histHeight - 1), Point((i + bins + 1) * scale - 1, histHeight - intensity_green), Scalar(0, 255, 0));
        // 绘制蓝色分量的直方图
        rectangle(histImage, Point((i + bins * 2) * scale, histHeight - 1), Point((i + bins * 2 + 1) * scale - 1, histHeight - intensity_blue), Scalar(0, 0, 255));
    }
    // 显示直方图
    imshow("图像的RGB直方图", histImage);

    waitKey(0);
    return 0;
}

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【OpenCV • c++】直方图计算 的相关文章

  • EF Core Group By 翻译支持条件总和

    听说 EF Core 2 1 将支持翻译小组 我感到非常兴奋 我下载了预览版并开始测试它 但发现我在很多地方仍然没有得到翻译分组 在下面的代码片段中 对 TotalFlagCases 的查询将阻止翻译分组工作 无论如何 我可以重写这个以便我
  • 动态加载程序集的应用程序配置

    我正在尝试将模块动态加载到我的应用程序中 但我想为每个模块指定单独的 app config 文件 假设我的主应用程序有以下 app config 设置
  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • 不支持将数据直接绑定到存储查询(DbSet、DbQuery、DbSqlQuery)

    正在编码视觉工作室2012并使用实体模型作为我的数据层 但是 当页面尝试加载时 上面提到的标题 我使用 Linq 语句的下拉控件往往会引发未处理的异常 下面是我的代码 using AdventureWorksEntities dw new
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • 不同枚举类型的范围和可转换性

    在什么条件下可以从一种枚举类型转换为另一种枚举类型 让我们考虑以下代码 include
  • 使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道

    当我执行以下代码时 System Net ServicePointManager ServerCertificateValidationCallback sender certificate chain errors gt return t
  • 将图像分割成多个网格

    我使用下面的代码将图像分割成网格的 20 个相等的部分 import cv2 im cv2 imread apple jpg im cv2 resize im 1000 500 imgwidth im shape 0 imgheight i
  • 创建链表而不将节点声明为指针

    我已经在谷歌和一些教科书上搜索了很长一段时间 我似乎无法理解为什么在构建链表时 节点需要是指针 例如 如果我有一个节点定义为 typedef struct Node int value struct Node next Node 为什么为了
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 这些作业之间是否存在顺序点?

    以下代码中的两个赋值之间是否存在序列点 f f x 1 1 x 2 不 没有 在这种情况下 标准确实是含糊不清的 如果你想确认这一点 gcc 有这个非常酷的选项 Wsequence point在这种情况下 它会警告您该操作可能未定义
  • cmake 将标头包含到每个源文件中

    其实我有一个简单的问题 但找不到答案 也许你可以给我指一个副本 所以 问题是 是否可以告诉 cmake 指示编译器在每个源文件的开头自动包含一些头文件 这样就不需要放置 include foo h 了 谢谢 CMake 没有针对此特定用例的
  • 如何在Xamarin中删除ViewTreeObserver?

    假设我需要获取并设置视图的高度 在 Android 中 众所周知 只有在绘制视图之后才能获取视图高度 如果您使用 Java 有很多答案 最著名的方法之一如下 取自这个答案 https stackoverflow com a 24035591
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • 如何将服务器服务连接到 Dynamics Online

    我正在修改内部管理应用程序以连接到我们的在线托管 Dynamics 2016 实例 根据一些在线教程 我一直在使用OrganizationServiceProxy out of Microsoft Xrm Sdk Client来自 SDK
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个

随机推荐

  • 2022产业区块链年度峰会暨FISCO BCOS五周年生态大会

    作为深圳国际金融科技节系列活动之一 由深圳市地方金融监督管理局指导 微众银行 金链盟主办的 2022产业区块链年度峰会暨FISCO BCOS五周年生态大会 将于2月24日下午 在深圳前海华侨城JW万豪酒店举行 此次大会以 数实相生 链筑可持
  • 垂直广告是什么意思_爆火的广告投放方式,抖音Feed流是什么?

    借势2020年的魔幻 短视频行业发展得如火如荼 年初的集体空闲 带动了各大短视频平台的发展 大量抖音创作者的涌入 也让出圈变得越来越难 为了更快出圈 有效利用流量 DOU 和Feed流应运而生 之前已经跟大家讲过DOU 投放的相关事宜 这期
  • 数据结构(三)- 数据的基本操作—增删查

    数据结构 三 增删查 文章目录 数据结构 三 增删查 前言 一 代码对数据的处理 二 数据处理的基本操作 总结 前言 数据最基本的操作 增删查 一 代码对数据的处理 在上篇文章数据结构 二 时间复杂度与空间复杂度中出现的一个例子 在一个数组
  • ubuntu16.04下如何训练PySOT(四):训练、测试、运行demo、评估

    下载预训练模型 从 Google Drive 下载 将预训练模型复制到 pretrained models 文件夹中 训练 在tools目录下打开终端 输入以下命令 即开始训练 CUDA VISIBLE DEVICES 0 python m
  • Matlab中米粒图像处理,米粒个数和大小计算

    clear clc 读取图片rice png I imread rice png 获取图片的背景 BG imopen I strel disk 15 得到背景均匀的图片 I2 imsubtract I BG 得到二值化的图片 level g
  • OpenStack常用命令搜集 —— 筑梦之路

    之前学习搭建过OpenStack 好久都没有使用了 这里主要搜集下OpenStack的常用命令 温故而知新 OpenStack 搭建记录 筑梦之路 筑梦之路的博客 CSDN博客 查看日志 日志位置 使用devstack方式部署 默认日志路径
  • Springboot使用future异步获取ip地址对应的地理位置

    future介绍 Future代表的是异步执行的结果 意思是当异步执行结束之后 返回的结果将会保存在Future中 那么我们什么时候会用到Future呢 一般来说 当我们执行一个长时间运行的任务时 使用Future就可以让我们暂时去处理其他
  • javax.net.ssl.SSLHandshakeException

    点击打开链接 以下是网上搜到的解决方案 在初始化httpclient实例前加上两行 ProtocolSocketFactory fcty new MySecureProtocolSocketFactory Protocol register
  • umijs中开启hd后配置的px2rem设置哪些样式转换为rem单位

    开启高清hd即使用rem单位 会自动把项目中的所有px单位转换为rem单位 并且根据屏幕大小自动调节html的基础font size 这样的好处一个网站不同大小分辨率效果基本一样 先贴一份umi的配置 config config js内容如
  • 副业怎么赚到钱?有哪些能赚钱的副业?

    副业怎么赚到钱 有哪些能赚钱的副业 所处城市偏僻的话 做网络上的副业最合适 不受地域限制 甚至在家 在路上 在单位工作间隙都能做 挣的跟一二线城市一样多 我列几个自己或者朋友真实做过的 都能挣到钱 就是没有月入过万那么夸张 一两千块还是很简
  • SoapUI、Jmeter、Postman三种接口测试工具的比较分析——灰蓝

    前段时间忙于接口测试 也看了几款接口测试工具 简单从几个角度做了个比较 拿出来与诸位分享一下吧 各位如果要转载 请一定注明来源 最好在评论中告知博主一声 感谢 本报告从多个方面对接口测试的三款常用工具进行比较分析 以便于在特定的情况下选择最
  • STL基本容器及算法

    STL 1 STL 常用容器 1 string 1 1基本概念 本质 string和C 风格的字符串 而string本质上是一个类 string和char 区别 char 是一个指针 string是一个类i 类内部封装了char 管理这个字
  • windows203+sql server 2000无法打开1433端口

    windows203 sql server 2000无法打开1433端口 1 如果你是win2003 那么一定要安装sql的补丁sp4 检查你的SQL有没有打补丁 没有的话要打上补丁 检查的方法是在查询分析器中运行 select versi
  • 如何构建多域名HTTPS代理服务器转发

    在当今互联网时代 安全可靠的网络访问是至关重要的 本文将介绍如何使用SNI Routing技术来构建多域名HTTPS代理服务器转发 轻松实现多域名的安全访问和数据传输 SNI代表 Server Name Indication 是TLS协议的
  • 接口测试 —— Requests库介绍

    1 Requests库 Requests库是用Python语言编写 基于urllib3模块 采用Apache2 Licensed开源协议的 HTTP 库 虽然Python的标准库中urllib3模块已经包含了平常我们使用的大多数功能 但是它
  • 2010.03.09(2)——Hibernate注解 无主键表

    2010 03 09 2 Hibernate注解 无主键表 今天写了个jfreechar从后台传数据的例子 就随便编了两个表 懒的写主键了 我用的是springmvc hibernate的方式 由于没有主键 我的注解如下 Entity Ta
  • 完整的 CentOS 系统服务器初始化配置、系统安全加固、系统内核参数优化以及常用软件安装脚本分享...

    描述 适用于企业内部 CentOS7 系列服务器初始化 系统安全加固脚本 内容包含了 网络初始化设置 软件更新源替换以及内核升级实践 时间时区初始化设置 系统安全加固 等保三级操作系统主机检查项 安全运维设置 系统内核参数 常用软件安装等
  • Vue技术_props配置(提高了组件的复用性)

    一 props简介 在Vue中 props属性是用于组件之间传递数据的一种机制 通过在子组件中定义props属性 可以接收父组件传递的数据 并在子组件中使用这些数据 下面是props属性的一些详细说明 1 定义和传递props 在子组件中使
  • 2.CMake的入门准备

    在计算机上获取以及安装CMake 在使用 CMake 之前 您需要在系统上安装或构建 CMake 二进制文件 在许多系统上 您可能会发现 CMake 已经安装或可以使用系统的标准包管理器工具进行安装 Cygwin Debian FreeBS
  • 【OpenCV • c++】直方图计算

    文章目录 一 什么是直方图 二 直方图的相关函数 1 计算直方图 calcHist 2 找寻最值 minMaxLoc 三 程序演示 1 色调 饱和度直方图 2 一维直方图 3 RGB 三色直方图 一 什么是直方图 直方图广泛应用于很多计算机