Opencv一维直方图的绘制

下面是我参考《opencv3编程入门》写的绘制一维直方图的代码

using namespace cv;
using namespace std;
#define byte uchar 
#define TYEPE_GRAY 0
#define TYEPE_RGB 1
/*--------------------------绘制RGB三色一维直方图-------------------------------------*/
Mat My_Rraw_histogram(Mat* srcImage,int type)  //输入:要处理的灰度图   输出:该图像的直方图
{if (type == TYEPE_GRAY)  //一维灰度直方图绘制{//【1】将原图转化为灰度图Mat gray_srcImage;cvtColor(*srcImage,gray_srcImage, COLOR_BGR2GRAY);//【2】定义变量MatND dstHist;int dims = 1;  //需要计算的直方图的维数float grayranges[] = { 0,255 };const float* ranges[] = { grayranges }; //这里需要为const类型int size = 256;   //表示的是将统计的灰度值分成的等份int Height = 256;int channels = 0; //灰度图只有一个0通道//【3】计算图像直方图calcHist(srcImage, //输入数组1, //数组个数&channels, //通道索引Mat(),//不使用掩膜dstHist, //输出的目标直方图dims, //需要计算的直方图的维数&size, //存放每个维度的直方图尺寸的数组ranges); //每一维数值的取值范围 int scale = 1;  //scale 每一个像素占的格数Mat dstImage(size * scale, size, CV_8U, Scalar(0));  //长 :size*scale ,宽:size ,值为0//【4】获取最大值和最小值double minVal = 0;double maxVal = 0;minMaxLoc(dstHist, &minVal, &maxVal, 0, 0);  //获得直方图中最大值和最小值//【5】绘制出直方图int hpt = saturate_cast<int>(0.9 * Height);   //saturate_cast 是溢出保护    大概意思 :if(data<int的负范围)  data = 负最大; else if (data > int的正范围) data = int 正最大;for (int i = 0;i < 256;i++){float binVal = dstHist.at<float>(i);int realVal = saturate_cast<int>(binVal * hpt / maxVal);  //在图像上的高度 = 像素数目/像素值最大数目 * 0.9*256   这里0.9是为了削减图像像素高度,因为最大的时候会触及顶端不美观rectangle(dstImage, Point(i * scale, Height - 1), Point((i + 1) * scale - 1, Height - realVal), Scalar(255));//要进行绘制的目标图像 矩形的左下顶点 矩阵对角线上的右上顶点 线条的颜色(RGB)或亮度(灰度图)  一共要绘制256个矩形}return dstImage;}else if (type == TYEPE_RGB){//【1】定义变量MatND redHist,greenHist,blueHist;int dims = 1;		//需要计算的直方图的维数float grayranges[] = { 0,256 };const float* ranges[] = { grayranges };	//这里需要为const类型int size = 256;			//表示的是将统计的灰度值分成的等份int channels_r[] = { 2 };	int channels_g[] = { 1 };	int channels_b[] = { 0 };	//疑问 : RGB图像的R、G、B是对应channel[0]、channel[1]、channel[2]还是对应channel[2]、channel[1]、channel[0] ?//经过验证是channel[2]、channel[1]、channel[0]//【2】计算图像直方图//--------------------red--------------------------calcHist(srcImage,	//输入数组1,	//数组个数channels_r,	//通道索引Mat(),//不使用掩膜redHist,	//输出的目标直方图dims,	//需要计算的直方图的维数&size,	//存放每个维度的直方图尺寸的数组ranges,//每一维数值的取值范围	true,//指示直方图是否均匀的标识符,true表示均匀的直方图false);	//累计标识符,false表示直方图在配置阶段会被清零//--------------------green--------------------------calcHist(srcImage,	//输入数组1,	//数组个数channels_g,	//通道索引Mat(),//不使用掩膜greenHist,	//输出的目标直方图dims,	//需要计算的直方图的维数&size,	//存放每个维度的直方图尺寸的数组ranges,//每一维数值的取值范围	true,//指示直方图是否均匀的标识符,true表示均匀的直方图false);	//累计标识符,false表示直方图在配置阶段会被清零//--------------------blue--------------------------calcHist(srcImage,	//输入数组1,	//数组个数channels_b,	//通道索引Mat(),//不使用掩膜blueHist,	//输出的目标直方图dims,	//需要计算的直方图的维数&size,	//存放每个维度的直方图尺寸的数组ranges,//每一维数值的取值范围	true,//指示直方图是否均匀的标识符,true表示均匀的直方图false);	//累计标识符,false表示直方图在配置阶段会被清零//【3】获取最大值和最小值double minVal_r = 0, minVal_g = 0, minVal_b = 0;double maxVal_r = 0, maxVal_g = 0,maxVal_b = 0;minMaxLoc(redHist, &minVal_r, &maxVal_r, 0, 0);		//获得r直方图中最大值和最小值minMaxLoc(greenHist, &minVal_g, &maxVal_g, 0, 0);		//获得g直方图中最大值和最小值minMaxLoc(blueHist, &minVal_b, &maxVal_b, 0, 0);		//获得b直方图中最大值和最小值int scale = 1;		//scale 每一个像素占的格数int Height = 256;	//直方图高度Mat dstImage(Height, size*3, CV_8UC3, Scalar(0,0,0));		//长 :size*scale ,宽:size*3 ,值为0  将三个直方图横放在一起//【4】绘制出直方图int hpt = saturate_cast<int>(0.9 * Height);			//saturate_cast 是溢出保护    大概意思 :if(data<int的负范围)  data = 负最大; else if (data > int的正范围) data = int 正最大;for (int i = 0;i < 256;i++){float binVal_r = redHist.at<float>(i);float binVal_g = greenHist.at<float>(i);float binVal_b = blueHist.at<float>(i);//疑问:是否存在一张图片中maxVal_r or maxVal_g or maxVal_b 有一个值为0?这样算出来的值将会是0/0, 而实际值应该是 0int intensityl_r = saturate_cast<int>(binVal_r * hpt / maxVal_r);		//在图像上的高度 = 像素数目/像素值最大数目 * 0.9*256   这里0.9是为了削减图像像素高度,因为最大的时候会触及顶端不美观int intensityl_g = saturate_cast<int>(binVal_g * hpt / maxVal_g);int intensityl_b = saturate_cast<int>(binVal_b * hpt / maxVal_b);rectangle(dstImage, Point(i * scale, Height - 1), Point((i + 1) * scale - 1, Height - intensityl_r), Scalar(0,0,255));rectangle(dstImage, Point((i+size)* scale, Height - 1), Point((i + size + 1)* scale - 1, Height - intensityl_g), Scalar(0,255,0));rectangle(dstImage, Point((i + 2*size)* scale, Height - 1), Point((i + 2*size + 1)* scale - 1, Height - intensityl_b), Scalar(255,0,0));//要进行绘制的目标图像 矩形的左下顶点 矩阵对角线上的右上顶点 线条的颜色(RGB)或亮度(灰度图)  一共要绘制256个矩形}return dstImage;} 
else{}
}
//主函数
int main()
{//【1】载入原图Mat srcImage = imread("D:\\opencv_picture_test\\RGB纯色图\\red.jpg", 2|4);			//原图//Mat srcImage = imread("D:\\opencv_picture_test\\JQ\\JQ14.jpg", 2 | 4);			//原图namedWindow("原图", WINDOW_NORMAL);//WINDOW_NORMAL允许用户自由伸缩窗口imshow("原图", srcImage);if (srcImage.empty()){printf("Could not find the image!\n");return -1;}Mat dstImage = My_Rraw_histogram(&srcImage, TYEPE_RGB);namedWindow("一维直方图", WINDOW_NORMAL);//WINDOW_NORMAL允许用户自由伸缩窗口imshow("一维直方图", dstImage);waitKey(0);return 0;
}

下面是代码实现的效果
原图纯红
一维直方图
纯红时,cahnnel【2】值为255的像素个数最多,其他为0,channel【1】和channel【0】值为0的像素个数最多,其他为0。

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

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

相关文章

Java类class forName()方法及示例

类类forName()方法 (Class class forName() method) forName() method is available in java.lang package. forName()方法在java.lang包中可用。 forName() method is used to return the class object for the Class with the given class_name. forName()方法用于返回具有给…

04-图像的阈值操作

对图像的阈值操作 import cv2 import matplotlib.pyplot as pltimg cv2.imread(E:/Jupyter_workspace/study/data/cat.png,1) ret, thresh1 cv2.threshold(img,127,255,cv2.THRESH_BINARY) ret, thresh2 cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV) ret, thresh3 c…

java虚拟机内存监控_深入理解JVM虚拟机9:JVM监控工具与诊断实践

本文转自&#xff1a;https://juejin.im/post/59e6c1f26fb9a0451c397a8c本系列文章将整理到我在GitHub上的《Java面试指南》仓库&#xff0c;更多精彩内容请到我的仓库里查看https://github.com/h3pl/Java-Tutorial喜欢的话麻烦点下Star哈文章将同步到我的个人博客&#xff1a;…

详解:数据库名、实例名、ORACLE_SID、数据库域名、全局数据库名、服务名

数据库名、实例名、数据库域名、全局数据库名、服务名&#xff0c;这是几个令很多初学者容易混淆的概念。相信很多初学者都与我一样被标题上这些个概念搞得一头雾水。我们现在就来把它们弄个明白。 一、数据库名什么是数据库名&#xff1f;数据库名就是一个数据库的标识&#…

颜色缩减 -利用指针、迭代器、动态地址实现访问像素

为什么要使用颜色缩减 在对单通道图像进行处理时&#xff0c;像素的可能值为256个&#xff0c;但处理多通道时&#xff0c;像素的处理就会相当麻烦&#xff0c;其实用这些颜色中具有代表性的一小部分就可以达到同样的效果&#xff0c;所以颜色空间缩减就可以派上用场了。一个信…

setlenient_Java日历setLenient()方法与示例

setlenient日历类setLenient()方法 (Calendar Class setLenient() method) setLenient() method is available in java.util package. setLenient()方法在java.util包中可用。 setLenient() method is used to set or unset lenient status of date or time interpretations. s…

PowerShell_9_零基础自学课程_9_高级主题:静态类和类的操作

哈哈&#xff0c;昨天弄了个ubuntu 11.10在虚拟机上运行&#xff0c;发现11.10界面非常绚丽&#xff0c;但是其需要的系统资源非常多&#xff0c;我虚拟机设定内存为512M&#xff0c;1个CPU4个核心&#xff0c; 进入以后发现根本动不了&#xff0c;因此今天我就下载了一个Fedor…

05-图像的平滑处理(不同的滤波操作)

对图像进行平滑处理实则就是对图像进行滤波操作罢了 每张图片都有若干个像素点所构成&#xff0c;滤波操作上就是将照片上的某些部分像素点进行修改从而达到平滑的效果 先展示一下原图 import cv2 img cv2.imread(E:\Jupyter_workspace\study\data/test1.png)cv2.imshow(te…

js删除mysql记录_(DELETEUPDATE)修改、删除数据记录_MySQL

有时&#xff0c;希望除去某些记录或更改它们的内容。DELETE 和 UPDATE 语句令我们能做到这一点。用update修改记录UPDATE tbl_name SET 要更改的列WHERE 要更新的记录这里的 WHERE 子句是可选的&#xff0c;因此如果不指定的话&#xff0c;表中的每个记录都被更新。例如&#…

C++设计模式之Abstract Factory模式

一、功能   提供一个创建一系列相关或相互依赖对象的接口&#xff0c;而无需指定它们具体的类。 二、结构图类厂最基本的结构示意图如下&#xff1a; 在实际应用中&#xff0c;类厂模式可以扩充到很复杂的情况&#xff0c;如下图所示&#xff1a; 三、优缺点 优点&#xff1…

数字图像处理小练习存档1

小练习的题目&#xff1a; 1、读取一张图&#xff0c;分解RGB三个通道 /************练习1**********************/ int main() {Mat img1 imread("D:\\opencv_picture_test\\miku2.jpg",2|4); //灰度图if (img1.empty()){printf("Could not find the imag…

UIImage 压缩

1.改变图片大小 -(UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize {// Create a graphics image contextUIGraphicsBeginImageContext(newSize);// Tell the old image to draw in this new context, with the desired// new size[image drawInRect:CG…

06-对图像进行腐蚀操作

形态学中的腐蚀操作一般处理的图像数据为二值的 cv2.erode(img,kernel,iterations 1) kernel表示拿多大的卷积核去腐蚀 iterations表示迭代次数 可以将一些带有毛毛的图像去毛毛化 原图 import cv2 import numpy as npdef show_photo(name,picture):cv2.imshow(name,picture)…

Java BufferedReader skip()方法与示例

BufferedReader类skip()方法 (BufferedReader Class skip() method) skip() method is available in java.io package. skip()方法在java.io包中可用。 skip() method is used to skip the given number of bytes of characters (n_bytes_of_char) from this BufferedReader. s…

mysql gtid binlog_MySQL之-四步实现BinLog Replication升级为GTIDs Replication的代码实例

1、将Master和Slave服务器都设置为read-onlymysql>SET global.read_onlyON;2、将Master与Slave服务器都停下来service mysql stop3、开启GTIDs开启GTIDs需要在master和slave服务器上都配置gtid-mode,log-bin,log-slave-updates,enforce-gtid-consistency(在MySQL 5.6.9之前是…

【记】琐碎

1.GIF载入问题:http://www.cnblogs.com/Lewis/archive/2011/01/17/1937066.html 2.正则分段数字&#xff1a; "12345678945612456".replace(new RegExp((\\d)(?(\\d{3})$),ig),"$1,") 其中用到了正则的后则判断? 3.给legend设定宽度 发现IE下可以 火狐下…

spring对事务的控制 AOP

我解释一下(* com.evan.crm.service.*.*(..))中几个通配符的含义&#xff1a; |第一个 * —— 通配 任意返回值类型| |第二个 * —— 通配 包com.evan.crm.service下的任意class| |第三个 * —— 通配 包com.evan.crm.service下的任意class的任意方法| |第四个 .. —— 通配 方…

Opencv实现利用滑动条来调整阈值

#include <opencv2/opencv.hpp> #include <iostream>using namespace cv; using namespace std; #define WINDOW_NAME "【程序窗口】" //为窗口标题定义的宏 //*--------------------------【练习】利用滑动条来调整阈值-----------------------------…

07-对图像进行膨胀操作

形态学中的膨胀操作即让照片变得更大&#xff0c;与腐蚀操作互为逆运算 cv2.dilate(erosion,kernel,iterations 1) 第一个参数&#xff1a;图像对象名称 第二个参数&#xff1a;卷积核的大小 第三个参数&#xff1a;迭代次数 此时就可与腐蚀操作进行相结合&#xff0c;腐蚀去毛…

Java LocalDate类| parse()方法与示例

LocalDate类parse()方法 (LocalDate Class parse() method) Syntax: 句法&#xff1a; public static LocalDate parse(CharSequence c_seq);public static LocalDate parse(CharSequence c_seq, DateTimeFormatter fmtr);parse() method is available in java.time package. …