C++OpenCV下绘制灰度直方图
C OpenCV下绘制直方图
直方图的定义:灰度直方图是对一幅灰度图像素分布的统计。对于一幅8Bit量化的图像来说。就是统计在0~255各个灰度级上,像素点的个数或者密度。
在OpenCV库提供了 calcHist()方法用于得到图像的直方图。
具体函数的调用方法如下:
void cv::calcHist(const Mat*images,int nimages,const int *channels,InputArrary mask,OutputArrary hist,int dims,const int* histSize,const float **ranges,bool uniform=true,bool accumulate=false)
//参数说明
//images:带统计直方图的图像数组
//nimages:输入图像的数目
//channels:需要统计的通道索引数组 一般灰度图就是0通道
//mask:掩码 一般填Mat()
//hist:输出的统计直方图结果,是一个dims维度的数组。不过用OpenCV中Mat类型的变量存储
//dims:hist的列数、需要计算直方图的维度
//histSize:存放每个维度直方图数组的尺寸
//ranges:每个通道灰度值的取值范围
根据以上参数,设计了一个获取直方图Mat数组Hist的函数
-
//@para gray:需要统计的图 Hist:用于存放统计数据
-
void GetHist(Mat gray,Mat &Hist) //统计8Bit量化图像的灰度直方图
-
{
-
const int channels[1] = { 0 }; //通道索引
-
float inRanges[2] = { 0,255 }; //像素范围
-
const float* ranges[1] = {inRanges};//像素灰度级范围
-
const int bins[1] = { 256 }; //直方图的维度
-
calcHist(&gray, 1, channels,Mat(), Hist,1, bins, ranges);
-
}
这里得gray为测试灰度图。看下运行完calcHist函数后,Hist的维数。
可以看到Hist就是一个256行1列Mat类型的变量,可以看做一个数组索引。
这样我们就可以根据这个Hist画图。
这里设计一个ShowHist函数,主要的步骤就是申请一块背景为纯黑的图像,再根据Hist的值转化为点坐标从而画出一个个白色的矩形以完成直方图的绘制。
-
void ShowHist(Mat &Hist)
-
{
-
//准备绘制直方图
-
int hist_w = 512;
-
int hist_h = 400;
-
int width = 2;
-
Mat histImage = Mat::zeros(hist_h,hist_w,CV_8UC3); //准备histImage为全黑背景色,大小为512*400
-
for (int i = 0; i < Hist.rows; i )
-
{
-
rectangle(histImage,Point(width*(i),hist_h-1),Point(width*(i 1),hist_h-cvRound(Hist.at<float>(i)/20)),
-
Scalar(255,255,255),-1);
-
}
-
namedWindow("histImage", WINDOW_AUTOSIZE);
-
imshow("histImage", histImage);
-
//waitKey(0);
-
}
首先准备一幅512*400的全黑背景图histImage,接下来通过Hist.rows遍历每个灰度级的像素个数。通过Rectangle函数画出白色的矩形。最后的-1代表绘制的矩形是填充矩形。对于Rectangle,重点分析下两个Point的含义。
@param pt1 Vertex of the rectangle.
@param pt2 Vertex of the rectangle opposite to pt1 .
上面是官方给出的注释,pt1为矩形的一个顶点,pt2为矩形对角线上的另一个顶点。
首先看横坐标,一个矩形的横坐标长度应该为一个像素级所占的长度,这里我们假定一个像素级占长度为width=2。pt1的横坐标值为width*(i),pt2的横坐标值为width*(i 1);
再看纵坐标,首先需要明白图像的坐标系,它是这样的:
pt1的纵坐标为:hist_h-1相当于图像最下面,也就是矩形的左下角。pt2的纵坐标应该是矩形的右上角才对,hist_h-cvRound(Hist.at<float>(i)/20),cvRound是4舍5入,Hist.at<float>(i)取出在该像素级上像素点的个数,这个数字可能远远大于hist_h(512),因为直方图我们只希望看到图像像素级分布的大致,所以我们除以一个20保证不会超出图像的边界。
最后给出我主函数的调用:
-
int main(int argc,char *argv)
-
{
-
Mat src,gray,hist; //hist用于统计gray的直方图
-
src=imread("2.jpg");
-
cvtColor(src,gray,CV_BGR2GRAY);
-
GetHist(gray,hist);
-
ShowHist(hist);
-
namedWindow("gray");
-
imshow("gray",gray);
-
waitKey(0);
-
return 0;
-
}
结果:
总结分析:其实图像的直方图只能告诉我们图像像素级别的分布如何,可以定性的帮助我们判断图像对比度,以及亮度的分布情况,如果想通过直方图进行操作,还是得借助calcHist得到的Hist数组对其进行定量的操作。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgfkibg
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13