Opencv绘制HSV颜色直方图

article/2025/9/28 12:19:37

一. 使用Opencv绘制HSV颜色直方图

所用的函数

cvCvtColor

可在: 使用Opencv将RGB颜色空间转换到HSV颜色空间/灰度图 文章中查找相关介绍

所使用的结构体:

CvHistogram 

以及函数:

cvCalcHist
CvCreateHist
cvGetMinMaxHistValue
cvConvertScale
cvReleaseHist

可在: 使用Opencv绘制灰度直方图/对比 文章中查找对应的函数介绍

 

1. 开始编写代码

准备一张实验图

如有需要,自行保存到本地,JPG格式!

1.1 打开测试图

1.2 创建三个用来分别绘制H,S,V的直方图

//打开测试图  IplImage * image = cvLoadImage("D:\\2.jpg", 1);           //将本地测试图导入到程序堆中  if (image == NULL){                                     //判断是否打开成功  printf("错误:无法打开该图像,图像文件路径不正确!");return -1;}

1.3 RGB颜色空间到HSV颜色空间转换

//创建一张空白图像用于存储转换成HSV颜色空间后的图像  IplImage *image1 = cvCreateImage(cvSize(image->width, image->height), image->depth, image->nChannels);  //注意图像必须和输入图像的size,颜色位深度,通道一致  cvZero(image1); //清空image_data数据  //颜色空间转换  cvCvtColor(image, image1, CV_BGR2HSV);//CV_BGR2HSV 

1.4 创建存储HSV通道图像

//创建存储HSV通道图像  IplImage *image_h = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像  IplImage *image_s = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像  IplImage *image_v = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像  

1.5 分离通道

//分离通道  cvSplit(image, image_h, image_s, image_v, NULL); //注意Opencv中hsv没有顺序问题

1.6 创建通道直方图

 

//创建H通道的直方图  int arr_size_h = 255;                 //定义一个变量用于表示直方图行宽  float hranges_arr_h[] = { 0, 180 };       //图像方块范围数组  float *phranges_arr_h = hranges_arr_h;      //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参  CvHistogram *hist_h = cvCreateHist(1, &arr_size_h, CV_HIST_ARRAY, &phranges_arr_h, 1);    //创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-180,bin均化 //创建S通道的直方图  int arr_size_s = 255;                 //定义一个变量用于表示直方图行宽  float hranges_arr_s[] = { 0, 255 };       //图像方块范围数组  float *phranges_arr_s = hranges_arr_s;      //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参  CvHistogram *hist_s = cvCreateHist(1, &arr_size_s, CV_HIST_ARRAY, &phranges_arr_s, 1);    //创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-255,bin均化 //创建V通道的直方图  int arr_size_v = 255;                 //定义一个变量用于表示直方图行宽  float hranges_arr_v[] = { 0, 255 };       //图像方块范围数组  float *phranges_arr_v = hranges_arr_v;      //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参  CvHistogram *hist_v = cvCreateHist(1, &arr_size_v, CV_HIST_ARRAY, &phranges_arr_v, 1);    //创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-255,bin均化 

1.7 计算通道直方图大小

//计算H通道的直方图大小cvCalcHist(&image_h, hist_h, 0, 0);//计算S通道的直方图大小cvCalcHist(&image_s, hist_s, 0, 0);//计算V通道的直方图大小cvCalcHist(&image_v, hist_v, 0, 0);

1.8 直方图缩小

//H通道的直方图缩小float max_val_h;  //用于存储获取到的最大值cvGetMinMaxHistValue(hist_h, 0, &max_val_h, 0, 0); //获取直方图最大值  cvConvertScale(hist_h->bins, hist_h->bins, max_val_h ? 180 / max_val_h : 0., 0);  //按比例缩小直方图  //S通道的直方图缩小float max_val_s;  //用于存储获取到的最大值cvGetMinMaxHistValue(hist_s, 0, &max_val_s, 0, 0); //获取直方图最大值  cvConvertScale(hist_s->bins, hist_s->bins, max_val_s ? 255 / max_val_s : 0., 0);  //按比例缩小直方图  //V通道的直方图缩小float max_val_v;  //用于存储获取到的最大值cvGetMinMaxHistValue(hist_v, 0, &max_val_v, 0, 0); //获取直方图最大值  cvConvertScale(hist_v->bins, hist_v->bins, max_val_v ? 255 / max_val_v : 0., 0);  //按比例缩小直方图  

1.9 绘制直方图

 

 

 

//创建一个空白图像用于绘制直方图  IplImage *histimg = cvCreateImage(cvSize(320, 200), 8, 3);cvZero(histimg);    //清空histimag-imagedata数据  //开始绘制H通道的直方图  int bin_h;bin_h = histimg->width / arr_size_h; //得到开始绘制点位置  for (int i = 0; i < arr_size_h; i++){double val = (cvGetReal1D(hist_h->bins, i)*histimg->height / 360);//获取矩阵元素值,并转换为对应高度  CvScalar color = CV_RGB(255, 0, 0);                                              cvRectangle(histimg, cvPoint(i*bin_h, histimg->height), cvPoint((i + 1)*bin_h, (int)(histimg->height - val)), color, 1, 8, 0);}//创建一个空白图像用于绘制直方图  IplImage *sistimg = cvCreateImage(cvSize(320, 200), 8, 3);cvZero(sistimg);    //清空histimag-imagedata数据  //开始绘制S通道的直方图  int bin_s;bin_s = sistimg->width / arr_size_s; //得到开始绘制点位置  for (int i = 0; i < arr_size_s; i++){double val = (cvGetReal1D(hist_s->bins, i)*sistimg->height / 255);//获取矩阵元素值,并转换为对应高度  CvScalar color = CV_RGB(0, 255, 0);cvRectangle(sistimg, cvPoint(i*bin_s, sistimg->height), cvPoint((i + 1)*bin_s, (int)(sistimg->height - val)), color, 1, 8, 0);}//创建一个空白图像用于绘制直方图  IplImage *vistimg = cvCreateImage(cvSize(320, 200), 8, 3);cvZero(vistimg);    //清空histimag-imagedata数据 //开始绘制V通道的直方图  int bin_v;bin_v = vistimg->width / arr_size_v; //得到开始绘制点位置  for (int i = 0; i < arr_size_v; i++){double val = (cvGetReal1D(hist_v->bins, i)*vistimg->height / 255);//获取矩阵元素值,并转换为对应高度  CvScalar color = CV_RGB(0, 0, 255);cvRectangle(vistimg, cvPoint(i*bin_v, vistimg->height), cvPoint((i + 1)*bin_v, (int)(vistimg->height - val)), color, 1, 8, 0);}

2.0 显示图像

//显示图像cvNamedWindow("image_hsv",0);cvNamedWindow("H",0);cvNamedWindow("S",0);cvNamedWindow("V",0);cvShowImage("image_hsv", image1);cvShowImage("H", histimg);cvShowImage("S", sistimg);cvShowImage("V", vistimg);cvWaitKey(0);//message

运行结果:

 

 

 

完整代码:

//打开测试图  IplImage * image = cvLoadImage("D:\\3.jpg", 1);           //将本地测试图导入到程序堆中  if (image == NULL){                                     //判断是否打开成功  printf("错误:无法打开该图像,图像文件路径不正确!");return -1;}//RGB颜色空间到HSV颜色空间//创建一张空白图像用于存储转换成HSV颜色空间后的图像  IplImage *image1 = cvCreateImage(cvSize(image->width, image->height), image->depth, image->nChannels);  //注意图像必须和输入图像的size,颜色位深度,通道一致  cvZero(image1); //清空image_data数据  //颜色空间转换  cvCvtColor(image, image1, CV_BGR2HSV);//CV_BGR2HSV //创建存储HSV通道图像  IplImage *image_h = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像  IplImage *image_s = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像  IplImage *image_v = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像  //分离通道  cvSplit(image, image_h, image_s, image_v, NULL); //注意Opencv中hsv没有顺序问题//创建H通道的直方图  int arr_size_h = 255;                 //定义一个变量用于表示直方图行宽  float hranges_arr_h[] = { 0, 180 };       //图像方块范围数组  float *phranges_arr_h = hranges_arr_h;      //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参  CvHistogram *hist_h = cvCreateHist(1, &arr_size_h, CV_HIST_ARRAY, &phranges_arr_h, 1);    //创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-180,bin均化 //创建S通道的直方图  int arr_size_s = 255;                 //定义一个变量用于表示直方图行宽  float hranges_arr_s[] = { 0, 255 };       //图像方块范围数组  float *phranges_arr_s = hranges_arr_s;      //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参  CvHistogram *hist_s = cvCreateHist(1, &arr_size_s, CV_HIST_ARRAY, &phranges_arr_s, 1);    //创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-255,bin均化 //创建V通道的直方图  int arr_size_v = 255;                 //定义一个变量用于表示直方图行宽  float hranges_arr_v[] = { 0, 255 };       //图像方块范围数组  float *phranges_arr_v = hranges_arr_v;      //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参  CvHistogram *hist_v = cvCreateHist(1, &arr_size_v, CV_HIST_ARRAY, &phranges_arr_v, 1);    //创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-255,bin均化 //计算H通道的直方图大小cvCalcHist(&image_h, hist_h, 0, 0);//计算S通道的直方图大小cvCalcHist(&image_s, hist_s, 0, 0);//计算V通道的直方图大小cvCalcHist(&image_v, hist_v, 0, 0);//H通道的直方图缩小float max_val_h;  //用于存储获取到的最大值cvGetMinMaxHistValue(hist_h, 0, &max_val_h, 0, 0); //获取直方图最大值  cvConvertScale(hist_h->bins, hist_h->bins, max_val_h ? 180 / max_val_h : 0., 0);  //按比例缩小直方图  //S通道的直方图缩小float max_val_s;  //用于存储获取到的最大值cvGetMinMaxHistValue(hist_s, 0, &max_val_s, 0, 0); //获取直方图最大值  cvConvertScale(hist_s->bins, hist_s->bins, max_val_s ? 255 / max_val_s : 0., 0);  //按比例缩小直方图  //V通道的直方图缩小float max_val_v;  //用于存储获取到的最大值cvGetMinMaxHistValue(hist_v, 0, &max_val_v, 0, 0); //获取直方图最大值  cvConvertScale(hist_v->bins, hist_v->bins, max_val_v ? 255 / max_val_v : 0., 0);  //按比例缩小直方图  //创建一个空白图像用于绘制直方图  IplImage *histimg = cvCreateImage(cvSize(320, 200), 8, 3);cvZero(histimg);    //清空histimag-imagedata数据  //开始绘制H通道的直方图  int bin_h;bin_h = histimg->width / arr_size_h; //得到开始绘制点位置  for (int i = 0; i < arr_size_h; i++){double val = (cvGetReal1D(hist_h->bins, i)*histimg->height / 360);//获取矩阵元素值,并转换为对应高度  CvScalar color = CV_RGB(255, 0, 0);                                              cvRectangle(histimg, cvPoint(i*bin_h, histimg->height), cvPoint((i + 1)*bin_h, (int)(histimg->height - val)), color, 1, 8, 0);}//创建一个空白图像用于绘制直方图  IplImage *sistimg = cvCreateImage(cvSize(320, 200), 8, 3);cvZero(sistimg);    //清空histimag-imagedata数据  //开始绘制S通道的直方图  int bin_s;bin_s = sistimg->width / arr_size_s; //得到开始绘制点位置  for (int i = 0; i < arr_size_s; i++){double val = (cvGetReal1D(hist_s->bins, i)*sistimg->height / 255);//获取矩阵元素值,并转换为对应高度  CvScalar color = CV_RGB(0, 255, 0);cvRectangle(sistimg, cvPoint(i*bin_s, sistimg->height), cvPoint((i + 1)*bin_s, (int)(sistimg->height - val)), color, 1, 8, 0);}//创建一个空白图像用于绘制直方图  IplImage *vistimg = cvCreateImage(cvSize(320, 200), 8, 3);cvZero(vistimg);    //清空histimag-imagedata数据 //开始绘制V通道的直方图  int bin_v;bin_v = vistimg->width / arr_size_v; //得到开始绘制点位置  for (int i = 0; i < arr_size_v; i++){double val = (cvGetReal1D(hist_v->bins, i)*vistimg->height / 255);//获取矩阵元素值,并转换为对应高度  CvScalar color = CV_RGB(0, 0, 255);cvRectangle(vistimg, cvPoint(i*bin_v, vistimg->height), cvPoint((i + 1)*bin_v, (int)(vistimg->height - val)), color, 1, 8, 0);}//显示图像cvNamedWindow("image_hsv",0);cvNamedWindow("H",0);cvNamedWindow("S",0);cvNamedWindow("V",0);cvShowImage("image_hsv", image1);cvShowImage("H", histimg);cvShowImage("S", sistimg);cvShowImage("V", vistimg);cvWaitKey(0);//message

 

 

 


http://chatgpt.dhexx.cn/article/bEbSCifg.shtml

相关文章

基于颜色直方图优化的图像增强方法

最近改图像颜色迁移的论文&#xff0c;审稿人要求补充基于直方图优化的方法细节。趁此机会&#xff0c;我重新下载了相关文献&#xff0c;决定重新学习下该类方法&#xff0c;并把一些细节记录在本篇博客中&#xff0c;供交流学习。 目录 1. 前言 2. 背景知识 3. 颜色变换 4. 颜…

[OpenCV实战]52 在OpenCV中使用颜色直方图

颜色直方图是一种常见的图像特征&#xff0c;顾名思义颜色直方图就是用来反映图像颜色组成分布的直方图。颜色直方图的横轴表示像素值或像素值范围&#xff0c;纵轴表示该像素值范围内像素点的个数或出现频率。颜色直方图属于计算机视觉中的基础概念&#xff0c;其常常被应用于…

关于颜色直方图

一、颜色距 转自&#xff1a;https://blog.csdn.net/jaych/article/details/51137341 1、颜色距离 颜色距离指的是两个颜色之间的差距&#xff0c;通常距离越大&#xff0c;两个颜色相差越大&#xff0c;反之&#xff0c;两个颜色越相近。在计算颜色距离时&#xff0c;有类似…

图像特征分析---颜色特征描述---颜色距和颜色直方图

一、颜色距 转自&#xff1a;https://blog.csdn.net/jaych/article/details/51137341 1、颜色距离颜色距离指的是两个颜色之间的差距&#xff0c;通常距离越大&#xff0c;两个颜色相差越大&#xff0c;反之&#xff0c;两个颜色越相近。在计算颜色距离时&#xff0c;有类似计算…

颜色特征提取(一)——颜色直方图(opencv实现)

直方图——再讲颜色直方图之前&#xff0c;先简单介绍一下直方图。 直方图作为一种简单有效的基于统计特性的特征描述子&#xff0c;在计算机视觉领域广泛使用。它的优点主要体现在两个方面:一是对于任意一个图像区域&#xff0c;直方图特征的提取简单方便;其二&#xff0c;直…

一般颜色直方图

颜色直方图是一种用于图像处理和分析的图表&#xff0c;它可以显示图像中不同颜色的数量。通常&#xff0c;颜色直方图会将颜色分成几个色调区间&#xff0c;每个区间对应一个条形图&#xff0c;其中条形图的高度表示该色调区间中的像素数量。通过颜色直方图&#xff0c;你可以…

网络爬虫Jsoup

简介 网络爬虫&#xff08;又称为网页蜘蛛&#xff0c;网络机器人&#xff0c;在FOAF社区中间&#xff0c;更经常的称为网页追逐者&#xff09;&#xff0c;是一种按照一定的规则&#xff0c;自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、…

【Java】Jsoup爬虫快速入门案例

1、前言 该技术博客是根据B站狂神说Java教程的笔记总结&#xff0c;希望能为大家带来帮助&#xff01; 2、Jsoup实战案例 爬虫可以理解为爬取数据&#xff0c;所谓爬取数据就是&#xff1a; 获取请求返回的页面信息&#xff0c;筛选出我们想要的数据 如果想要爬取数据&#…

android爬虫框架jsoup,Android笔记之JSoup爬虫入门

前言 闲扯一些没用的&#xff0c;写这篇文章之前是有点私心的&#xff0c;因为之前评论某简书大v的文章是鸡汤&#xff0c;瞬间被拉黑&#xff0c;连个解释和说明的机会都没有&#xff0c;文章语言干涩&#xff0c;内容平平&#xff0c;于是就好奇到底是些什么样的人喜欢和吹捧…

Java的Jsoup爬虫

Java的Jsoup爬虫&#xff0c;爬携程酒店评分&#xff0c;保存数据库中 前言一、Jsoup爬虫pom二、逻辑代码部分1.首先我们要先确定爬取的东西&#xff0c;这边我就以携程的酒店评分为例子。2.Jsoup进行解析具体要求爬的内容3.接下来我们就是将爬取的数据存入数据库中 总结 前言 …

使用Jsoup爬虫爬取相关图片

一、Jsoup概述 jsoup 是一款Java 的HTML解析器&#xff0c;可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API&#xff0c;可通过DOM&#xff0c;CSS以及类似于jQuery的操作方法来取出和操作数据。 主要功能&#xff1a; 1. 从一个URL&#xff0c;文件或字符串…

jsoup爬虫实战详解之新浪

** jsoup爬虫实战详解之新浪 ** 今天分享一个之前困扰了一段时间的关于jsoup爬取新浪网页信息的踩坑总结。 在实现以上功能的之前我门首先要了解两个重点&#xff1a;1.关于jsoup的爬取细节以及教程&#xff0c;爬取时所要了解jsoup的相关标签&#xff1a;具体的自己大家感兴…

Java JSOUP爬虫学习分享

昨天从狂神大佬那学习了如何用jsoup爬去网站数据&#xff0c;现在整理了一下给大家分享一下。 先创建一个名叫JsoupPojo的实体类用来装入数据。 Data public class JsoupPojo {private String src;private String name; } 下面是将用来爬取的方法封装成了一个工具类 Compon…

java jsoup爬虫

前言&#xff1a;在日常开发中&#xff0c;我们必定是与我们的数据源打交道&#xff0c;我们的数据源无非就那么几个 1.数据库2.爬虫数据 3.第三方系统交互&#xff0c;这里介绍java 中网页版的爬虫jsoup的使用 1.首先导入我们的jar包 maven坐标如下 org.jsoup jsoup 1.13.1 c…

Jsoup爬虫并解析网页

Jsoup爬虫并解析网页 京东搜索 java&#xff0c;爬取有关java的商品信息 1、获取请求 String url"https://search.jd.com/Search?keywordjava";2、解析网页。&#xff08;Jsoup返回的Document对象就是浏览器的Document对象&#xff09; 所有js中操作Document对象的…

Jsoup爬虫入门实战

一、Jsoup介绍 jsoup 是一款基于 Java 的HTML解析器&#xff0c;它提供了一套非常省力的API&#xff0c;不但能直接解析某个URL地址、HTML文本内容&#xff0c;而且还能通过类似于DOM、CSS或者jQuery的方法来操作数据&#xff0c;所以 jsoup 也可以被当做爬虫工具使用。 相关…

Jsoup爬虫实例

一、简介 jsoup 是一款Java 的HTML解析器&#xff0c;可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API&#xff0c;可通过DOM&#xff0c;CSS以及类似于jQuery的操作方法来取出和操作数据。&#xff08;来源百度&#xff09; 二、准备 首先你需要找到一个你…

使用Jsoup实现网络爬虫

一、什么是Jsoup&#xff1f; jsoup是一款Java的HTML解析器、可以通过URL获取DOM元素并解析&#xff0c;也可对HTML文本内容进行解析&#xff0c;jsoup提供了一套非常简单的方法&#xff0c;类似于CSS、JQuery的操作方法对元素或者是数据进行操作。 二、Jsoup的特点及作用 从…

Java学习笔记:爬虫-用Jsoup解析网页

什么是爬虫 1、爬虫&#xff1a;程序代替人的人工操作&#xff0c;自动获取网页内容&#xff0c;并且从其中提取出来有价值信息。 2、原始&#xff1a;调用Http的类向服务器发出请求&#xff0c;获得HTML&#xff0c;然后用正则表达式等去分析。缺点&#xff1a;难度高。 3、…

jsoup爬虫

文章目录 1、jsoup爬虫简单介绍2、相关代码2.1导入pom依赖2.2、图片爬取2.3、图片本地化 3、百度云链接爬虫 1、jsoup爬虫简单介绍 jsoup 是一款 Java 的HTML 解析器&#xff0c;可通过DOM&#xff0c;CSS选择器以及类似于JQuery的操作方法来提取和操作Html文档数据。 这两个…