c++视觉处理----绘制直方图,H—S直方图,二维H—S直方图,RGB三色直方图

2023-10-14 02:01

本文主要是介绍c++视觉处理----绘制直方图,H—S直方图,二维H—S直方图,RGB三色直方图,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

直方图:cv::calcHist()

cv::calcHist() 是 OpenCV 中用于计算直方图的函数。直方图是一种用于可视化图像亮度或颜色分布的工具。这函数通常应用于灰度图像或彩色图像的各个通道。以下是 cv::calcHist() 函数的基本语法和参数:

void cv::calcHist(const cv::Mat* images, // 输入图像的数组int nimages,           // 输入图像的数量const int* channels,   // 通道索引数组(可以为空)const cv::InputArray& mask, // 掩模图像(可以为空)cv::OutputArray& hist,      // 输出的直方图int dims,                 // 直方图的维数const int* histSize,      // 直方图的尺寸数组const float* ranges[],    // 直方图范围数组bool uniform = true,      // 直方图是否均匀分布bool accumulate = false   // 是否累积直方图
);

以下是参数的说明:

  • images:输入图像的数组,可以是一个或多个图像。
  • nimages:输入图像的数量,通常为1。
  • channels:通道索引数组,指定要计算直方图的通道。对于灰度图像,通常为0。对于彩色图像,通道索引可以是{0, 1, 2},分别代表蓝色、绿色和红色通道。
  • mask:可选的掩模图像,用于限制计算直方图的区域。可以为空。
  • hist:输出的直方图。
  • dims:直方图的维数。通常为1。
  • histSize:直方图的尺寸数组,表示直方图的柱数。
  • ranges:直方图范围数组,指定直方图的范围。通常为{0, 256},表示像素值的范围。
  • uniform:指定是否将直方图均匀分布,如果为true,每个直方柱的宽度相同。
  • accumulate:指定是否累积直方图,如果为true,直方图将被累积。

cv::calcHist() 函数用于计算直方图后,你可以进一步分析或可视化直方图数据。这对于图像处理、分析和计算机视觉任务非常有用。

以下是一个更完整的 cv::calcHist() 函数的示例,它将计算一幅图像的直方图并绘制出来。这个示例假定你已经读取了一幅图像,并且使用灰度图像计算直方图:

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>int main() {// 读取图像cv::Mat image = cv::imread("your_image.jpg");if (image.empty()) {std::cerr << "Error: Could not read the image." << std::endl;return -1;}// 将图像转换为灰度图像cv::Mat gray_image;cv::cvtColor(image, gray_image, cv::COLOR_BGR2GRAY);// 定义直方图的参数int histSize = 256; // 直方图中的条柱数量float range[] = {0, 256}; // 像素值范围const float* histRange = {range};// 计算直方图cv::Mat hist;cv::calcHist(&gray_image, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange);// 创建一个空的直方图图像int hist_w = 512;int hist_h = 400;cv::Mat hist_image(hist_h, hist_w, CV_8UC3, cv::Scalar(0, 0, 0));// 归一化直方图cv::normalize(hist, hist, 0, hist_image.rows, cv::NORM_MINMAX, -1, cv::Mat());// 绘制直方图for (int i = 1; i < histSize; i++) {cv::line(hist_image, cv::Point(i - 1, hist_h - cvRound(hist.at<float>(i - 1))),cv::Point(i, hist_h - cvRound(hist.at<float>(i))),cv::Scalar(255, 255, 255), 2, 8, 0);}// 显示原始图像和直方图cv::namedWindow("Original Image", cv::WINDOW_AUTOSIZE);cv::imshow("Original Image", gray_image);cv::namedWindow("Histogram", cv::WINDOW_AUTOSIZE);cv::imshow("Histogram", hist_image);cv::waitKey(0);return 0;
}

这个示例将图像转换为灰度图像,计算其直方图,然后绘制直方图并显示原始图像以及对应的直方图。希望这个示例可以帮助你理解如何使用 cv::calcHist() 函数来计算和可视化图像的直方图。
在这里插入图片描述

绘制H—S直方图

#include <opencv2/opencv.hpp>int main() {// 读取图像cv::Mat image = cv::imread("1.jpg");if (image.empty()) {std::cerr << "Error: Could not read the image." << std::endl;return -1;}// 将图像转换为HSV颜色空间cv::Mat hsv_image;cv::cvtColor(image, hsv_image, cv::COLOR_BGR2HSV);// 分割H和S通道std::vector<cv::Mat> channels;cv::split(hsv_image, channels);// 定义直方图的参数int histSize = 256; // 直方图中的条柱数量float hRange[] = { 0, 256 }; // 色相通道的像素值范围const float* hHistRange = { hRange };float sRange[] = { 0, 256 }; // 饱和度通道的像素值范围const float* sHistRange = { sRange };// 计算H和S通道的直方图cv::Mat h_hist, s_hist;cv::calcHist(&channels[0], 1, 0, cv::Mat(), h_hist, 1, &histSize, &hHistRange);cv::calcHist(&channels[1], 1, 0, cv::Mat(), s_hist, 1, &histSize, &sHistRange);// 归一化直方图cv::normalize(h_hist, h_hist, 0, 255, cv::NORM_MINMAX, -1, cv::Mat());cv::normalize(s_hist, s_hist, 0, 255, cv::NORM_MINMAX, -1, cv::Mat());// 创建一个直方图图像int hist_w = 512;int hist_h = 400;cv::Mat hist_image(hist_h, hist_w, CV_8UC3, cv::Scalar(0, 0, 0));// 绘制H通道直方图for (int i = 1; i < histSize; i++) {cv::line(hist_image, cv::Point(i - 1, hist_h - cvRound(h_hist.at<float>(i - 1))),cv::Point(i, hist_h - cvRound(h_hist.at<float>(i))),cv::Scalar(0, 0, 255), 2, 8, 0);}// 绘制S通道直方图for (int i = 1; i < histSize; i++) {cv::line(hist_image, cv::Point(i - 1, hist_h - cvRound(s_hist.at<float>(i - 1))),cv::Point(i, hist_h - cvRound(s_hist.at<float>(i))),cv::Scalar(0, 255, 0), 2, 8, 0);}// 显示图像和H-S直方图cv::imshow("mage", image);cv::imshow("H-S Histogram", hist_image);cv::waitKey(0);return 0;
}

在这里插入图片描述

绘制二维H—S直方图

#include <opencv2/opencv.hpp>int main() {// 读取图像cv::Mat image = cv::imread("1.jpg");if (image.empty()) {std::cerr << "Error: Could not read the image." << std::endl;return -1;}// 将图像转换为HSV颜色空间cv::Mat hsv_image;cv::cvtColor(image, hsv_image, cv::COLOR_BGR2HSV);// 定义直方图的参数int h_bins = 30; // 色相通道的柱数int s_bins = 32; // 饱和度通道的柱数int histSize[] = {h_bins, s_bins};float h_range[] = {0, 180}; // 色相通道的范围float s_range[] = {0, 256}; // 饱和度通道的范围const float* ranges[] = {h_range, s_range};// 计算H-S直方图cv::MatND hist;int channels[] = {0, 1}; // 色相和饱和度通道cv::calcHist(&hsv_image, 1, channels, cv::Mat(), hist, 2, histSize, ranges, true, false);// 归一化直方图cv::normalize(hist, hist, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());// 创建一个H-S直方图图像int hist_w = 512;int hist_h = 512;cv::Mat hist_image(hist_h, hist_w, CV_8UC3, cv::Scalar(0, 0, 0));// 绘制直方图for (int h = 0; h < h_bins; h++) {for (int s = 0; s < s_bins; s++) {float bin_val = hist.at<float>(h, s);int intensity = cvRound(bin_val * 255);cv::rectangle(hist_image, cv::Point(h * (hist_w / h_bins), s * (hist_h / s_bins)),cv::Point((h + 1) * (hist_w / h_bins), (s + 1) * (hist_h / s_bins)),cv::Scalar(intensity, intensity, intensity), -1);}}// 显示原始图像和H-S直方图cv::imshow("Image", image);cv::imshow("H-S Histogram", hist_image);cv::waitKey(0);return 0;
}

在这里插入图片描述

绘制RGB三色直方图

#include <opencv2/opencv.hpp>int main() {// 读取图像cv::Mat image = cv::imread("1.jpg");if (image.empty()) {std::cerr << "Error: Could not read the image." << std::endl;return -1;}// 定义直方图的参数int histSize = 256; // 直方图中的条柱数量float range[] = { 0, 256 }; // 像素值范围const float* histRange = { range };// 分割RGB通道std::vector<cv::Mat> channels;cv::split(image, channels);// 计算红色通道的直方图cv::Mat red_hist;cv::calcHist(&channels[2], 1, 0, cv::Mat(), red_hist, 1, &histSize, &histRange);// 计算绿色通道的直方图cv::Mat green_hist;cv::calcHist(&channels[1], 1, 0, cv::Mat(), green_hist, 1, &histSize, &histRange);// 计算蓝色通道的直方图cv::Mat blue_hist;cv::calcHist(&channels[0], 1, 0, cv::Mat(), blue_hist, 1, &histSize, &histRange);// 归一化直方图cv::normalize(red_hist, red_hist, 0, 255, cv::NORM_MINMAX, -1, cv::Mat());cv::normalize(green_hist, green_hist, 0, 255, cv::NORM_MINMAX, -1, cv::Mat());cv::normalize(blue_hist, blue_hist, 0, 255, cv::NORM_MINMAX, -1, cv::Mat());// 创建一个直方图图像int hist_w = 512;int hist_h = 400;cv::Mat hist_image(hist_h, hist_w, CV_8UC3, cv::Scalar(0, 0, 0));// 绘制红色通道直方图for (int i = 1; i < histSize; i++) {cv::line(hist_image, cv::Point(i - 1, hist_h - cvRound(red_hist.at<float>(i - 1))),cv::Point(i, hist_h - cvRound(red_hist.at<float>(i))),cv::Scalar(0, 0, 255), 2, 8, 0);}// 绘制绿色通道直方图for (int i = 1; i < histSize; i++) {cv::line(hist_image, cv::Point(i - 1, hist_h - cvRound(green_hist.at<float>(i - 1))),cv::Point(i, hist_h - cvRound(green_hist.at<float>(i))),cv::Scalar(0, 255, 0), 2, 8, 0);}// 绘制蓝色通道直方图for (int i = 1; i < histSize; i++) {cv::line(hist_image, cv::Point(i - 1, hist_h - cvRound(blue_hist.at<float>(i - 1))),cv::Point(i, hist_h - cvRound(blue_hist.at<float>(i))),cv::Scalar(255, 0, 0), 2, 8, 0);}// 显示原始图像和RGB三色直方图cv::imshow("mage", image);cv::imshow("RGB Histogram", hist_image);cv::waitKey(0);return 0;
}

在这里插入图片描述

这篇关于c++视觉处理----绘制直方图,H—S直方图,二维H—S直方图,RGB三色直方图的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/207378

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

poj2576(二维背包)

题意:n个人分成两组,两组人数只差小于1 , 并且体重只差最小 对于人数要求恰好装满,对于体重要求尽量多,一开始没做出来,看了下解题,按照自己的感觉写,然后a了 状态转移方程:dp[i][j] = max(dp[i][j],dp[i-1][j-c[k]]+c[k]);其中i表示人数,j表示背包容量,k表示输入的体重的 代码如下: #include<iostream>#include<

hdu2159(二维背包)

这是我的第一道二维背包题,没想到自己一下子就A了,但是代码写的比较乱,下面的代码是我有重新修改的 状态转移:dp[i][j] = max(dp[i][j], dp[i-1][j-c[z]]+v[z]); 其中dp[i][j]表示,打了i个怪物,消耗j的耐力值,所得到的最大经验值 代码如下: #include<iostream>#include<algorithm>#include<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)