opencv对直方图的计算和绘制

【欢迎关注编码小哥,学习更多实用的编程方法和技巧】

1、直方图的计算

cv::calcHist 是 OpenCV 中用于计算图像直方图的函数。它可以处理多通道图像,并通过指定图像、通道、掩膜、直方图大小和范围等参数来生成直方图。

函数原型

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: 要计算的原图,类型为 const Mat*,表示一个图像数组。
  • nimages: 图像数组的大小,类型为 int
  • channels: 指定计算的通道,类型为 const int*,表示一个通道数组。每个通道对应一个图像。
  • mask: 用于计算特定区域的掩膜,类型为 InputArray,表示一个图像或矩形区域。
  • hist: 输出的直方图,类型为 OutputArray,表示一个多维数组。
  • dims: 直方图的维度,类型为 int,表示直方图的维度。
  • histSize: 直方图的大小,类型为 const int*,表示一个大小数组,每个大小对应一个维度。
  • ranges: 像素值范围,类型为 const float**,表示一个范围数组,每个范围对应一个维度。
  • uniform: 是否使用均匀的直方图,类型为 bool,默认为 true
  • accumulate: 是否累积计算结果,类型为 bool,默认为 false

返回值

  • 无返回值,该函数直接修改输出直方图。
  • #include <opencv2/opencv.hpp>int main() {// 读取图像cv::Mat img = cv::imread("image.jpg");// 计算灰度图直方图cv::Mat gray;cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);int histSize = 256;float range[] = {0, 256};cv::Mat hist;cv::calcHist(&gray, 1, &0, cv::Mat(), hist, 1, &histSize, &range);// 计算彩色图直方图int channels[] = {0, 1, 2};cv::Mat hist_b, hist_g, hist_r;cv::calcHist(&img, 1, channels, cv::Mat(), hist_b, 1, &histSize, &range);cv::calcHist(&img, 1, channels + 1, cv::Mat(), hist_g, 1, &histSize, &range);cv::calcHist(&img, 1, channels + 2, cv::Mat(), hist_r, 1, &histSize, &range);// 绘制直方图cv::Mat hist_img(256, 256, CV_8UC3);cv::normalize(hist, hist, 0, hist_img.rows, cv::NORM_MINMAX);for (int i = 0; i < histSize; i++) {cv::line(hist_img, cv::Point(i, hist_img.rows), cv::Point(i, hist_img.rows - cvRound(hist.at<float>(i))), cv::Scalar(255, 0, 0));}cv::imshow("Histogram", hist_img);cv::waitKey(0);cv::destroyAllWindows();return 0;
    }

  • cv::calcHist 函数可以处理多通道图像,但必须指定计算的通道。
  • cv::calcHist 函数可以计算多个直方图,但必须具有相同的尺寸和类型。
  • cv::calcHist 函数可以累积计算结果,但必须指定输出直方图。

2、一维直方图的绘制

一维直方图是一种常见的数据可视化方法,用于显示数据的分布情况。在 OpenCV 中,可以使用以下步骤绘制一维直方图:

  1. 计算直方图:使用 cv::calcHist 函数计算图像的直方图。
  2. 归一化直方图:使用 cv::normalize 函数将直方图归一化到指定的范围。
  3. 绘制直方图:使用 cv::line 函数绘制直方图。
#include <opencv2/opencv.hpp>int main() {// 读取图像cv::Mat img = cv::imread("image.jpg");// 计算灰度图直方图cv::Mat gray;cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);int histSize = 256;float range[] = {0, 256};cv::Mat hist;cv::calcHist(&gray, 1, &0, cv::Mat(), hist, 1, &histSize, &range);// 归一化直方图cv::Mat hist_norm;cv::normalize(hist, hist_norm, 0, 256, cv::NORM_MINMAX);// 绘制直方图cv::Mat hist_img(256, 256, CV_8UC3);for (int i = 0; i < histSize; i++) {cv::line(hist_img, cv::Point(i, hist_img.rows), cv::Point(i, hist_img.rows - cvRound(hist_norm.at<float>(i))), cv::Scalar(255, 0, 0));}// 显示直方图cv::imshow("Histogram", hist_img);cv::waitKey(0);cv::destroyAllWindows();return 0;
}

 在这个示例中,我们首先读取一张图像,然后计算其灰度图直方图。接着,我们将直方图归一化到 0-256 的范围,然后绘制直方图。最后,我们显示直方图。

注意:在绘制直方图时,我们使用 cv::line 函数绘制每个直方图条。我们将直方图条的高度设置为 hist_img.rows - cvRound(hist_norm.at<float>(i)),以便直方图条的高度与直方图值成比例。

如果想绘制彩色图直方图,可以使用以下代码:

// 计算彩色图直方图
int channels[] = {0, 1, 2};
cv::Mat hist_b, hist_g, hist_r;
cv::calcHist(&img, 1, channels, cv::Mat(), hist_b, 1, &histSize, &range);
cv::calcHist(&img, 1, channels + 1, cv::Mat(), hist_g, 1, &histSize, &range);
cv::calcHist(&img, 1, channels + 2, cv::Mat(), hist_r, 1, &histSize, &range);// 归一化直方图
cv::Mat hist_b_norm, hist_g_norm, hist_r_norm;
cv::normalize(hist_b, hist_b_norm, 0, 256, cv::NORM_MINMAX);
cv::normalize(hist_g, hist_g_norm, 0, 256, cv::NORM_MINMAX);
cv::normalize(hist_r, hist_r_norm, 0, 256, cv::NORM_MINMAX);// 绘制直方图
cv::Mat hist_img(256, 256, CV_8UC3);
for (int i = 0; i < histSize; i++) {cv::line(hist_img, cv::Point(i, hist_img.rows), cv::Point(i, hist_img.rows - cvRound(hist_b_norm.at<float>(i))), cv::Scalar(255, 0, 0));cv::line(hist_img, cv::Point(i, hist_img.rows), cv::Point(i, hist_img.rows - cvRound(hist_g_norm.at<float>(i))), cv::Scalar(0, 255, 0));cv::line(hist_img, cv::Point(i, hist_img.rows), cv::Point(i, hist_img.rows - cvRound(hist_r_norm.at<float>(i))), cv::Scalar(0, 0, 255));
}

在这个示例中,我们计算彩色图的直方图,然后归一化直方图。接着,我们绘制直方图,每个通道使用不同的颜色。

3、多维直方图的绘制 

2D直方图是一种用于表示两个变量之间关系的数据可视化方法。在 OpenCV 中,可以使用以下步骤绘制 2D 直方图:

  1. 计算直方图:使用 cv::calcHist 函数计算图像的直方图。
  2. 归一化直方图:使用 cv::normalize 函数将直方图归一化到指定的范围。
  3. 绘制直方图:使用 cv::imshow 函数显示直方图。

以下是示例代码:

#include <opencv2/opencv.hpp>int main() {// 读取图像cv::Mat img = cv::imread("image.jpg");// 计算 2D 直方图int channels[] = {0, 1};int histSize[] = {256, 256};float range[] = {0, 256, 0, 256};cv::Mat hist;cv::calcHist(&img, 1, channels, cv::Mat(), hist, 2, histSize, range);// 归一化 2D 直方图cv::Mat hist_norm;cv::normalize(hist, hist_norm, 0, 256, cv::NORM_MINMAX);// 绘制 2D 直方图cv::Mat hist_img(256, 256, CV_8UC3);for (int i = 0; i < 256; i++) {for (int j = 0; j < 256; j++) {int index = i * 256 + j;cv::Vec3b color = cv::Vec3b(i, j, 0);hist_img.at<cv::Vec3b>(i, j) = color * (hist_norm.at<float>(index) / 256.0f);}}// 显示 2D 直方图cv::imshow("2D Histogram", hist_img);cv::waitKey(0);cv::destroyAllWindows();return 0;
}

 在这个示例中,我们计算 2D 直方图,然后归一化 2D 直方图。接着,我们绘制 2D 直方图,每个像素的颜色根据 2D 直方图值计算。

注意:在绘制 2D 直方图时,我们使用 cv::Vec3b 类型表示颜色,每个颜色通道的值根据 2D 直方图值计算。

如果想绘制 3D 直方图,可以使用以下代码:

// 计算 3D 直方图
int channels[] = {0, 1, 2};
int histSize[] = {256, 256, 256};
float range[] = {0, 256, 0, 256, 0, 256};
cv::Mat hist;
cv::calcHist(&img, 1, channels, cv::Mat(), hist, 3, histSize, range);// 归一化 3D 直方图
cv::Mat hist_norm;
cv::normalize(hist, hist_norm, 0, 256, cv::NORM_MINMAX);// 绘制 3D 直方图
cv::Mat hist_img(256, 256, CV_8UC3);
for (int i = 0; i < 256; i++) {for (int j = 0; j < 256; j++) {for (int k = 0; k < 256; k++) {int index = i * 256 * 256 + j * 256 + k;cv::Vec3b color = cv::Vec3b(i, j, k);hist_img.at<cv::Vec3b>(i, j) = color * (hist_norm.at<float>(index) / 256.0f);}}
}// 显示 3D 直方图
cv::imshow("3D Histogram", hist_img);
cv::waitKey(0);
cv::destroyAllWindows();

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

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

相关文章

C++的auto_ptr智能指针:从诞生到被弃用的历程

C作为一种功能强大的编程语言&#xff0c;为开发者提供了众多便捷的特性和工具&#xff0c;其中智能指针是其重要特性之一。智能指针能够自动管理内存&#xff0c;有效避免内存泄漏等常见问题。然而&#xff0c;并非所有智能指针都尽善尽美&#xff0c;auto_ptr便是其中的一个例…

游戏开发中常用的设计模式

目录 前言一、工厂模式二、单例模式三、观察者模式观察者模式的优势 四、状态模式状态模式的优势 五、策略模式策略模式的优势策略模式与状态模式有什么区别呢? 六、组合模式七、命令模式八、装饰器模式 前言 本文介绍了游戏开发中常用的设计模式&#xff0c;如工厂模式用于创…

C++并发编程之异常安全性增强

在并发编程中&#xff0c;异常安全是一个非常重要的方面&#xff0c;因为并发环境下的错误处理比单线程环境更加复杂。当多个线程同时执行时&#xff0c;异常不仅可能影响当前线程&#xff0c;还可能影响其他线程和整个程序的稳定性。以下是一些增强并发程序异常安全性的方法&a…

各语言镜像配置汇总

镜像配置汇总 Nodejs [ npm ]Python [ pip ] Nodejs [ npm ] // # 记录日期&#xff1a;2025-01-20// 查询当前使用的镜像 npm get registry// 设置淘宝镜像 npm config set registry https://registry.npmmirror.com/// 恢复为官方镜像 npm config set registry https://regi…

Navicat Premium 数据可视化

工作区&#xff0c;数据源以及图表 数据可视化是使用可视化组件&#xff08;例如图表&#xff0c;图形和地图&#xff09;的信息和数据的图形表示。 数据可视化工具提供了一种可访问的方式&#xff0c;用于查看和理解数据中的趋势&#xff0c;异常值和其他模式。 在Navicat中&…

linux通过web向mac远程传输字符串,mac收到后在终端中直接打印。

要通过Web从Linux向Mac远程传输字符串&#xff0c;并在Mac的终端中直接打印&#xff0c;可以使用以下方法。这里假设Linux作为服务器&#xff0c;Mac作为客户端。 方法 1&#xff1a;使用Python的HTTP服务器 在Linux上启动一个简单的HTTP服务器&#xff0c;Mac通过curl获取字符…

【系统分享01】Python+Vue电影推荐系统

大家好&#xff0c;作为一名老程序员&#xff0c;今天我将带你一起走进电影推荐系统的世界&#xff0c;分享如何利用 Django REST Framework 和 Vue 搭建一套完整的电影推荐系统&#xff0c;结合 协同过滤算法&#xff0c;根据用户评分与影片喜好&#xff0c;精准推送用户可能喜…

Spring Boot+Vue

Spring BootVue 前后端分离是一种非常流行且高效的开发模式&#xff0c;以下是关于其相关方面的详细介绍&#xff1a; 前端&#xff08;Vue&#xff09;部分 • 项目搭建 • 使用 Vue CLI 创建项目&#xff0c;它提供了丰富的插件和配置选项&#xff0c;能够快速生成项目基础…

第十四章:计算机新技术

文章目录&#xff1a; 一&#xff1a;云计算 二&#xff1a;大数据 三&#xff1a;物联网 四&#xff1a;人工智能 五&#xff1a;移动网络与应用 六&#xff1a;电子商务 七&#xff1a;虚拟实现 八&#xff1a;区块链 一&#xff1a;云计算 概念云基于⽹络&#xff0…

【大数据2025】MapReduce

MapReduce 基础介绍 起源与发展&#xff1a;是 2004 年 10 月谷歌发表的 MAPREDUCE 论文的开源实现&#xff0c;最初用于大规模网页数据并行处理&#xff0c;现成为 Hadoop 核心子项目之一&#xff0c;是面向批处理的分布式计算框架。基本原理&#xff1a;分为 map 和 reduce …

主从复制

简述mysql 主从复制原理及其工作过程&#xff0c;配置一主两从并验证。 主从原理&#xff1a;MySQL 主从同步是一种数据库复制技术&#xff0c;它通过将主服务器上的数据更改复制到一个或多个从服务器&#xff0c;实现数据的自动同步。 主从同步的核心原理是将主服务器上的二…

【博客之星评选】2024年度前端学习总结

故事的开端...始于2024年第一篇前端技术博客 那故事的终末...也该结束于陪伴了我一整年的前端知识了 踏入 2025 年&#xff0c;满心激动与自豪&#xff0c;我成功闯进了《2024 年度 CSDN 博客之星总评选》的 TOP300。作为一名刚接触技术写作不久的萌新&#xff0c;这次能走到这…

Ubuntu 24.04 LTS 服务器折腾集

目录 Ubuntu 更改软件源Ubuntu 系统语言英文改中文windows 远程链接 Ubuntu 图形界面Windows 通过 openssh 连接 UbuntuUbuntu linux 文件权限Ubuntu 空闲硬盘挂载到 文件管理器的 other locationsUbuntu 开启 SMB 服务&#xff0c;并通过 windows 访问Ubuntu安装Tailscale&am…

《TikTok停服:信息安全警钟长鸣》

一、TikTok 停服事件回顾 2025 年 1 月 18 日晚&#xff0c;TikTok 通知美国用户&#xff0c;由于美官方禁令于 19 日起生效&#xff0c;TikTok 软件将暂时对用户停止服务。这一消息犹如一颗重磅炸弹&#xff0c;瞬间在全球范围内掀起轩然大波。美国用户对此猝不及防&#xff0…

1166 Summit (25)

A summit (峰会) is a meeting of heads of state or government. Arranging the rest areas for the summit is not a simple job. The ideal arrangement of one area is to invite those heads so that everyone is a direct friend of everyone. Now given a set of tenta…

图论DFS:黑红树

我的个人主页 {\large \mathsf{{\color{Red} 我的个人主页} } } 我的个人主页 往 {\color{Red} {\Huge 往} } 往 期 {\color{Green} {\Huge 期} } 期 文 {\color{Blue} {\Huge 文} } 文 章 {\color{Orange} {\Huge 章}} 章 DFS 算法&#xff1a;记忆化搜索DFS 算法&#xf…

C++,设计模式,【目录篇】

文章目录 1. 简介2. 设计模式的分类2.1 创建型模式&#xff08;Creational Patterns&#xff09;&#xff1a;2.2 结构型模式&#xff08;Structural Patterns&#xff09;&#xff1a;2.3 行为型模式&#xff08;Behavioral Patterns&#xff09;&#xff1a; 3. 使用设计模式…

掌握提示词工程:大模型使用入门指南

掌握提示词工程&#xff1a;大模型使用入门指南 近年来&#xff0c;大语言模型&#xff08;如 GPT、Claude 等&#xff09;的强大能力令人印象深刻&#xff0c;但要想充分发挥这些模型的潜力&#xff0c;仅仅依靠其预训练能力还不够。提示词工程&#xff08;Prompt Engineerin…

如何使用 useMemo 和 memo 优化 React 应用性能?

使用 useMemo 和 memo 优化 React 应用性能 在构建复杂的 React 应用时&#xff0c;性能优化是确保应用流畅运行的关键。React 提供了多种工具来帮助开发者优化组件的渲染和计算逻辑&#xff0c;其中 useMemo 和 memo 是两个非常有用的 Hook。本文将详细介绍这两个工具的使用方…

Agent Laboratory: Using LLM Agents as Research Assistants 论文简介

加速机器学习研究的智能实验室——Agent Laboratory 1. 引言 随着人工智能技术的飞速发展&#xff0c;机器学习领域正以前所未有的速度推进科学发现和技术创新。然而&#xff0c;传统的科学研究模式往往受到时间、资源和专业知识限制&#xff0c;阻碍了研究者们探索新想法的能…