【C++的OpenCV】第十一课-OpenCV图像常用操作(八):直方图计算(cv.calc())

news2025/7/7 22:23:59

🎉🎉🎉 欢迎各位来到小白 p i a o 的学习空间! \color{red}{欢迎各位来到小白piao的学习空间!} 欢迎各位来到小白piao的学习空间!🎉🎉🎉
💖💖💖 持续更新,期待关注! \color{blue}{持续更新,期待关注!} 持续更新,期待关注!💖💖💖
🤞🤞🤞 目前已经为大家更新了: \color{green}{目前已经为大家更新了:} 目前已经为大家更新了:🤞🤞🤞

  1. Python基础、中级、高级;
  2. C++数据结构和算法;
  3. OpenCV相关内容等重点内容

🌹🌹🌹 我的主页: \color{purple}{我的主页:} 我的主页:我的主页🌹🌹🌹

目录

  • 前言
  • 一、图像直方图的计算
    • 1.1 cv.calcHist()函数
    • 1.2 实例代码
    • 1.3 结果

前言

        上一章内容中,为大家简单介绍了图像直方图,和直方图均衡化的目的和相关的案例源码,本章节我们将继续深化这部分内容,因为这部分内容也是一个比较有意思的内容。本章内容主要围绕cv.calcHist()的使用方法展开,为大家详细介绍它的用法,注重实际使用!请认真看看哈。


前文链接:【C++的OpenCV】第十课-OpenCV图像常用操作(七):直方图和直方图同等化(直方图均衡化)


一、图像直方图的计算

1.1 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 
					)		
/*
参数解释:
images:需要计算直方图的源图像阵列集
	注意:它们都应该具有相同的深度、CV_8U、CV_16U或CV_32F以及相同的大
	小。它们中的每一个都可以具有任意数量的通道。
nimages:这个图像阵列中,图像的个数
channels:用于计算直方图中的每个维度的每个通道的列表,需要统计的图像的通道集合(是一个整型数组,且数组值不可变)。
mask:掩膜,如果掩膜非空,
	那么这个掩膜必须是和源图像阵列中的图像同样大小的8位图像数组。
hist:存放经过直方图计算后的图像
dims:直方图的维度,直方图维度必须为正且不大于CV_MAX_DIMS(在当前OpenCV版本中等于32)
histSize:每个维度上直方图的尺寸大小
ranges:每个维度上直方图二进制边界的维度数组的数组,是一个二位数组。当直方图是均匀的(uniform=true)时,对于每个维度,只需指定第0个直方图的下(含)边界和最后一个直方图的上(不含)边界即可,即,在均匀直方图的情况下,每个范围是2个元素的阵列。当直方图不一致(uniform=false)时,则每个范围i中包含histSize[i]+1个元素:L0,U0=L1,U1=L2,....... ,UhistSize[i]−2=LhistSize[i]−1,UhistSize[i]−1。不在L0和UhistSize[i]−1之间的数组元素不计入直方图中。
uniform:直方图是否进行归一化处理,true为是,false为否
accumulate:累计,是否累计,如果已设置,则分配直方图时不会在开始时清除直方图。此功能使您能够从多组数组中计算单个直方图,或及时更新直方图。
*/

  • 原型二:

void cv::calcHist	(	
						const Mat * 	images,
						int 	nimages,
						const int * 	channels,
						InputArray 	mask,
						SparseMat & 	hist,
						int 	dims,
						const int * 	histSize,
						const float ** 	ranges,
						bool 	uniform = true,
						bool 	accumulate = false 
					)	
/*
参数解释:
hist : 只有这个参数的类型与第一种原型不同,故解释一下:只是说以SparseMat类型的图像作为直方图输出的结果。
*/

  • 原型三:

void cv::calcHist	(	
						InputArrayOfArrays 	images,
						const std::vector< int > & 	channels,
						InputArray 	mask,
						OutputArray 	hist,
						const std::vector< int > & 	histSize,
						const std::vector< float > & 	ranges,
						bool 	accumulate = false 
					)	
/*
参数解释:
这个里边的 channels、histSize、ranges都存放在了vector容器当中而已。
但是需要注意的是,这个函数仅仅可以被用于归一化处理的直方图的计算。
range参数要么是空向量,要么是histSize.size()*2个元素(histSize.shize()元素对)的展平向量。每对的第一和第二元素指定下边界和上边界。
*/

1.2 实例代码

//实例一:
#include "opencv2/highgui.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>

using namespace std;
using namespace cv;

int main(int argc, char** argv)
{
  Mat src, dst;
  String imageName( "/home/aelx-chen/demo.jpg" ); //指定一个图片路径
  src = imread( imageName ); // 读取这个路径下的图片放在这个src容器当中
  if( src.empty() ) //图片判空
    { return -1; }
  vector<Mat> bgr_planes; // 创建装源图像的图像容器vector
  split( src, bgr_planes );//将这个图像在RGB三个通道分别分离出来。记得到三个通道的三张图片存放在bgr_planes中
  int histSize = 256; //设置直方图大小
  float range[] = { 0, 256 } ; // 指定饱和度范围在0~255中。
  const float* histRange = { range };
  bool uniform = true; bool accumulate = false;
  Mat b_hist, g_hist, r_hist;
  calcHist( &bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate );
  calcHist( &bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate );
  calcHist( &bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate ); 
  //上边是计算三个通道三张图片的直方图。
  //下边是画出这三条折线图(过点划线),当然你也可以使用rectangle去绘制条形图。当然如果是Python,则可以借助三方库matlab中的方法直接完成绘图。
  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( 0,0,0) ); 
//利用Mat的重写的构造函数构造一个histImage图像对象
//用于存储均质化(规范化一个数组的标准范围或者数组中元素值的范围)的结果。
//这个图像的大小和直方图一样大。
  //标准化处理:
  normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
  normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
  normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
  for( int i = 1; i < histSize; i++ )//下边就是采点划线的过程了。
  {
      line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at<float>(i-1)) ) ,
                       Point( bin_w*(i), hist_h - cvRound(b_hist.at<float>(i)) ),
                       Scalar( 255, 0, 0), 2, 8, 0  );
      line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at<float>(i-1)) ) ,
                       Point( bin_w*(i), hist_h - cvRound(g_hist.at<float>(i)) ),
                       Scalar( 0, 255, 0), 2, 8, 0  );
      line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at<float>(i-1)) ) ,
                       Point( bin_w*(i), hist_h - cvRound(r_hist.at<float>(i)) ),
                       Scalar( 0, 0, 255), 2, 8, 0  );
  }
  namedWindow("calcHist Demo", WINDOW_AUTOSIZE );
  imshow("calcHist Demo", histImage );
  imshow("src", src);
  waitKey(0);
  return 0;

1.3 结果

在这里插入图片描述


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

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

相关文章

发布新闻稿的流程与步骤

发布新闻稿需要遵循一定的流程和步骤&#xff0c;以下是一般的新闻发布流程&#xff1a;1、编写新闻稿新闻稿的内容应当简洁、明确、准确&#xff0c;力求突出新闻价值和亮点。企业和组织可以根据新闻稿的主题和目的&#xff0c;选择不同的写作风格和语言表达方式&#xff0c;以…

春季训练营 | 前端+验证直通车-全实操项目实践,履历加成就业无忧

“芯动的offer”是2023年E课网联合企业全新推出集训培优班&#xff08;线下&#xff09;&#xff0c;针对有一定基础&#xff08;linux、verilog、uvm等&#xff09;在校学生以及想要通过短时间的学习进入到IC行业中的转行人士&#xff0c;由资深IC设计工程师带教&#xff0c;通…

openpnp - 贴片前, 放入一块新板子后, 对板子的坐标矫正

文章目录openpnp - 贴片前, 放入一块新板子后, 对板子的坐标矫正概述笔记实验前置条件实验开始建立自己板子上的Mark点封装, 用于自己人工圈定判断Mark点位置是否正确建立mark点封装根据多个mark点, 来精确定位板子左下角原点坐标ENDopenpnp - 贴片前, 放入一块新板子后, 对板子…

图像边缘检测

文章目录前言一、图像边缘检测二、边缘检测算子1. Roberts算子2. Prewitt算子3. Sobel算子三、代码实现总结前言 有了图像放大缩小&#xff0c;图像灰度化处理等相关基础知识过后&#xff0c;就可以进行图像边缘检测了。边缘检测最后也会在FPGA上面实现&#xff0c;此处小编已经…

神经网络分类任务(手写数字识别)

1.Mnist分类任务 网络基本构建与训练方法&#xff0c;常用函数解析 torch.nn.functional模块 nn.Module模块 学习方法&#xff1a;边用边查&#xff0c;多打印&#xff0c;duogua 使用jupyter的优点&#xff0c;可以打印出每一个步骤。 2.读取数据集 自动下载 %matplotl…

移动设备配置文件管理

什么是移动设备上的设备配置文件 随着移动设备在工作中使用量的迅速增加&#xff0c;有必要将这些设备置于企业管理之下&#xff0c;以确保企业数据安全且设备符合行业标准。移动设备上的配置文件允许 IT 管理员通过对员工使用的智能手机、平板电脑和笔记本电脑实施公司策略和…

三维人脸实践:基于Face3D的渲染、生成与重构 <一>

face3d: Python tools for processing 3D face git code: https://github.com/yfeng95/face3d paper list: PaperWithCode 该方法广泛用于基于三维人脸关键点的人脸生成、属性检测&#xff08;如位姿、深度、PNCC等&#xff09;&#xff0c;能够快速实现人脸建模与渲染。推荐…

学生使用的台灯该怎么选择?2023适合学生房间的灯推荐

随着社会的进步发展&#xff0c;我们的生活水平越来越高&#xff0c;很多家庭的孩子都开始使用台灯这种家居产品&#xff0c;对于学习任务繁重的他们来说&#xff0c;台灯确实可以起到保护眼睛、提高学习专注度的作用。那么不知道朋友们是否了解过&#xff0c;台灯该怎么选择呢…

本地开发vue项目联调遇到访问接口跨域问题

本地开发vue项目联调遇到访问接口跨域问题 修改本地的localhost 一&#xff1a;按winr打开运行窗口&#xff0c;输入drivers &#xff0c;然后回车 二&#xff1a;打开etc文件夹&#xff0c;然后用记事本的方式打开里面的hosts文件&#xff0c; 三&#xff1a;这时我们就可…

oneblog_justauth_三方登录配置【QQ】

文章目录oneblog添加第三方平台QQ互联平台创建三方应用完善信息登录oneblog添加第三方平台 1.oneblog管理端&#xff0c;点击左侧菜单 网站管理——>社会化登录配置管理 ,添加一个社会化登录 2.编辑信息如下&#xff0c;选择QQ平台后复制redirectUri,然后去QQ互联平台获取…

UART 串口通信

第18.1讲 UART串口通信原理讲解_哔哩哔哩_bilibili 并行通信 一个周期同时发送8bit的数据&#xff0c;占用引脚资源多 串行通信 串行通信的通信方式&#xff1a; 同步通信 同一时钟下进行数据传输 异步通信 发送设备和接收设备的时钟不同 但是需要约束波特率&#xff08;…

大数据|HDFS分布式文件系统

前文回顾&#xff1a;Hadoop系统 目录 &#x1f4da;HDFS概述 &#x1f4da;HDFS在设计时的假设和目标 &#x1f4da;HDFS的基本特征 &#x1f4da;HDFS的体系结构 &#x1f407;目录节点 &#x1f407;数据节点 &#x1f4da;HDFS的副本机制 &#x1f4da;HDFS的数据存…

KD500全自动电容电感测试仪

一、产品特点 1.本仪器采用了先进的测量原理与四端测量技术&#xff0c;可以精确测量、测试重复性能好&#xff1b; 2.能在不拆线的状态下&#xff0c;测量成组并联着的单个电容器的电容量和成组并联着电容器组的总电容量&#xff1b; 3.大屏幕液晶显示屏&#xff08;320X24…

关于Activiti7审批工作流绘画流程图(2)

文章目录一、25张表详解二、安装插件一.定制流程提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、25张表详解 虽然表很多&#xff0c;但是仔细观察&#xff0c;我们会发现Activiti 使用到的表都是 ACT_ 开头的。表名的第二部分用两个字母表明表的用…

vuex基础之初始化功能、state、mutations、getters、模块化module的使用

vuex基础之初始化功能、state、mutations、getters、模块化module的使用一、Vuex的介绍二、初始化功能三、state3.1 定义state3.2 获取state3.2.1 原始形式获取3.2.2 辅助函数获取(mapState)四、mutations4.1 定义mutations4.2 调用mutations4.2.1 原始形式调用($store)4.2.2 辅…

数据分析方法及名词解释总结_(面试2)

1、用户画像 1.1、什么是用户画像&#xff1f;如何构建用户画像&#xff1f; - 知乎提到用户画像&#xff0c; 很多人都可能存在的错误认知&#xff0c;即把用户画像简单理解成用户各种特征&#xff0c;比如说姓名、性别、…https://www.zhihu.com/question/372802348/answer/2…

spi 子系统

spi在应用层的体现 spi 分为主机模式和从机模式&#xff0c;一般soc 自带的spi 控制器&#xff0c;我们都将它用作主机模式与外挂的从设备通信。从设备例如 oled芯片、flash芯片、陀螺仪芯片等等。 那么spi 驱动和设备&#xff0c;自然也就分为主机驱动、设备和从机驱动、设备…

云原生时代顶流消息中间件Apache Pulsar部署实操之Pulsar IO与Pulsar SQL

文章目录Pulsar IO (Connector连接器)基础定义安装Pulsar和内置连接器连接Pulsar到Cassandra安装cassandra集群配置Cassandra接收器创建Cassandra Sink验证Cassandra Sink结果删除Cassandra Sink连接Pulsar到PostgreSQL安装PostgreSQL集群配置JDBC接收器创建JDBC Sink验证JDBC …

redis cluster配置之read-mode

背景生产部署了redis集群&#xff0c;三台机器&#xff08;三主三从&#xff0c;主从不在同一台机器上&#xff09;&#xff0c;redission连接使用。当有一个master节点挂掉时&#xff0c;redis整个集群不可用。解决过程运维登上机器上&#xff0c;执行cluster info发现集群OK状…

JAVA开发(数据类型String和HasMap的实现原理)

在JAVA开发中&#xff0c;使用最多的数据类型恐怕是String 和 HasMap两种数据类型。在开发的过程中我们每天都使用的不亦乐乎。但是相信很多人都没有考虑过String数据类型的实现原理或者说是在数据结构中的存储原理&#xff0c;还有一个就是是HashMap&#xff0c;也很少有人去了…