1、直方图的概念

灰度直方图是灰度级的函数,描述的是图像中具有该灰度级的像元的个数。确定图像像素的灰度值范围,以适当的灰度间隔为单位将其划分为若干等级,以横轴表示灰度级,以纵轴表示每一灰度级具有的像素数或该像素占总像元数的比例值,做出的条形统计图即为灰度直方图。灰度直方图:横坐标是灰度,纵坐标是该灰度在图像中出现的次数。

图像直方图可以表示图像中亮度分布,能借助直方图了解需要如何调整亮度分布,直方图中左侧表示黑色、较暗的区域,右侧表示白色、较亮的区域。计算机视觉领域常借助直方图来实现图像的二值化。

2、OpenCV直方图

OpenCV使用calcHist函数实现直方图计算,函数原型如下图。

CV_EXPORTS void 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 );

参数详解:

onst Mat* images:输入图像组

int nimages:输入图像的个数

const int* channels:需要统计直方图的第几通道

InputArray mask:掩膜,计算掩膜内的直方图

OutputArray hist:输出的直方图的数组

int dims:直方图的维度,需要统计直方图通道的个数

const int* histSize:指的是直方图分成多少个区间,就是 bin的个数

const float** ranges: 统计像素值的区间,每个维度数值的取值范围

bool uniform=true:是否对得到的直方图数组进行归一化处理

bool accumulate=false:在多个图像时,是否累计计算像素值得个数

测试代码如下:

Mat src = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\img1.bmp");
imshow("原图", src); MatND dstHist;
int dims = ;
float hranges[] = { , };
const float *ranges[]= { hranges };
int size = ;
int channels = ; calcHist(&src, , &channels, Mat(), dstHist, dims, &size, ranges); double maxVal = ;
double minVal = ;
cv::minMaxLoc(dstHist, &minVal, &maxVal, , );
Mat histImg(size, size, CV_8U, cv::Scalar());
int hpt = static_cast<int>(0.9*size); for (int h = ; h < ; h++)
{
float binVal = dstHist.at<float>(h);
int intensity = static_cast<int>(binVal * hpt / maxVal);
cv::line(histImg, Point(h, size-), Point(h+, size- - intensity), Scalar::all());
} imshow("直方图", histImg);
waitKey();

输出结果为:

如果是彩色图像,则可以计算RGB通道各自的直方图。

测试代码如下:

Mat src = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\pic5.bmp");
imshow("原图", src); int histsize = ;
float range[] = { , };
const float*histRanges = { range }; vector<Mat>bgr_planes;
split(src, bgr_planes);
Mat b_hist, g_hist, r_hist;
calcHist(&bgr_planes[], , , Mat(), b_hist, , &histsize, &histRanges, true, false);
calcHist(&bgr_planes[], , , Mat(), g_hist, , &histsize, &histRanges, true, false);
calcHist(&bgr_planes[], , , Mat(), r_hist, , &histsize, &histRanges, true, false); Mat histImg = Mat::zeros(, *, CV_8UC3);
for (int h = ; h < ; h++)
{
float binVal_r = r_hist.at<float>(h);
float binVal_g = g_hist.at<float>(h);
float binVal_b = b_hist.at<float>(h); rectangle(histImg, Point(h, - ), Point(h + , - binVal_r), Scalar(, , ));
rectangle(histImg, Point(h+, - ), Point(h ++ , - binVal_g), Scalar(, , ));
rectangle(histImg, Point(h+, - ), Point(h + + , - binVal_b), Scalar(, , ));
}
imshow("直方图", histImg);

输出结果为:

3、直方图均衡化

直方图均衡化即灰度均衡化,通过灰度映射,使输入图像的灰度转换为在每一级灰度上都有近似相同的点数分布,这样输出的直方图就是均匀的,图像获得较高的对比度和较大的动态范围。直方图均衡化对图像进行非线性拉伸,重新分配图像像素值,使一定灰度范围内的像素数量大致相同。使用直方图均衡化技术来处理图像,能扩展图像的动态范围,扩宽灰度等级范围,提高对比度。

直方图均衡化可以调整较暗的图片,图片较暗,动态范围低,直方图灰度等级偏暗,均衡化后灰度基本平均分布。。

使用直方图均衡化,在处理较暗的图像时特别有效,如下测试。

Mat blue, green, red, dst;
blue = bgr_planes[];
green = bgr_planes[];
red = bgr_planes[]; equalizeHist(blue, blue);
equalizeHist(green, green);
equalizeHist(red, red);
merge(bgr_planes, , dst);
imshow("均衡化图", dst); vector<Mat> bgr_planes2;
split(dst, bgr_planes2);
calcHist(&bgr_planes2[], , , Mat(), b_hist, , &histsize, &histRanges, true, false);
calcHist(&bgr_planes2[], , , Mat(), g_hist, , &histsize, &histRanges, true, false);
calcHist(&bgr_planes2[], , , Mat(), r_hist, , &histsize, &histRanges, true, false); histImg = Mat::zeros(, * , CV_8UC3);
for (int h = ; h < ; h++)
{
float binVal_r = r_hist.at<float>(h);
float binVal_g = g_hist.at<float>(h);
float binVal_b = b_hist.at<float>(h); rectangle(histImg, Point(h, - ), Point(h + , - binVal_r), Scalar(, , ));
rectangle(histImg, Point(h + , - ), Point(h + + , - binVal_g), Scalar(, , ));
rectangle(histImg, Point(h + , - ), Point(h + + , - binVal_b), Scalar(, , ));
}

输出图像对比:

处理后的图片亮度提高,动态范围扩大,这里有一个问题,由于是全局处理,车牌由于反光材料本来就属于最亮的区域,均衡化后更亮了,导致车牌亮度过曝反而更加难识别了,所以需要特定的直方图处理。

对比直方图:

5、参考文献

1、《OpenCV3 编程入门》,电子工业出版社,毛星雨著

2、《学习OpenCV》,清华大学出版社,Gary Bradski, Adrian kaehler著

3、OpenCV图像直方图

https://blog.csdn.net/leonardohaig/article/details/88240112

4、图像处理基础(8):图像的灰度直方图、直方图均衡化、直方图规定化(匹配)

https://www.cnblogs.com/wangguchangqing/p/7098213.html

5、OpenCV实现图像的直方图处理

https://www.cnblogs.com/noticeable/p/10449867.html

6、【OpenCV学习笔记】之直方图(Histogram)

https://blog.csdn.net/zhu_hongji/article/details/81663161

技术博客,转载请注明。

https://www.cnblogs.com/pingwen/p/12380776.html

OpenCV3入门(十一)图像直方图的更多相关文章

  1. Python 图像处理 OpenCV (16):图像直方图

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  2. OpenCV成长之路(5):图像直方图的应用

    正如第4篇文章所说的图像直方图在特征提取方面有着很重要的作用,本文将举两个实际工程中非常实用的例子来说明图像直方图的应用. 一.直方图的反向映射. 我们以人脸检测举例,在人脸检测中,我们第一步往往需要 ...

  3. OpenCV成长之路(4):图像直方图

    一.图像直方图的概念 图像直方图是反映一个图像像素分布的统计表,其实横坐标代表了图像像素的种类,可以是灰度的,也可以是彩色的.纵坐标代表了每一种颜色值在图像中的像素总数或者占所有像素个数的百分比. 图 ...

  4. OpenCV成长之路:图像直方图的应用

    OpenCV成长之路:图像直方图的应用 2014-04-11 13:57:03 标签:opencv 图像 直方图 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否 ...

  5. OpenCV成长之路:图像直方图

    http://ronny.blog.51cto.com/8801997/1394115 2014-04-11 13:47:27 标签:opencv 直方图 统计表 原创作品,允许转载,转载时请务必以超 ...

  6. Python实现图像直方图均衡化算法

    title: "Python实现图像直方图均衡化算法" date: 2018-06-12T17:10:48+08:00 tags: [""] categorie ...

  7. 【python-opencv】图像直方图

    图像直方图使用到:python-opencv.matplotlib.numpy def plot_demo(image): print(len(image.ravel())) #统计image3通道的 ...

  8. Python+OpenCV图像处理(八)—— 图像直方图

    直方图简介:图像的直方图是用来表现图像中亮度分布的直方图,给出的是图像中某个亮度或者某个范围亮度下共有几个像素.还不明白?就是统计一幅图某个亮度像素数量.比如对于灰度值12,一幅图里面有2000 个像 ...

  9. 机器学习进阶-直方图与傅里叶变换-图像直方图 1.cv2.calc(生成图像的像素频数分布(直方图))

    1. cv2.calc([img], [0], mask, [256], [0, 256])  # 用于生成图像的频数直方图 参数说明: [img]表示输入的图片, [0]表示第几个通道, mask表 ...

随机推荐

  1. Spark宽依赖、窄依赖

    在Spark中,RDD(弹性分布式数据集)存在依赖关系,宽依赖和窄依赖. 宽依赖和窄依赖的区别是RDD之间是否存在shuffle操作. 窄依赖 窄依赖指父RDD的每一个分区最多被一个子RDD的分区所用 ...

  2. flutter 命令卡主的问题

    情况 1 镜像的问题 如果你的镜像已经设置,却仍然卡主,那么请参考情况 2 这种情况在中文官网上已经有了,并且有这修改镜像的方法,附上链接: https://flutter.cn/community/ ...

  3. ZEOSDBO控件的安装及使用方法

    步骤:1:下载最新版的ZEOSDBO,官网:http://sourceforge.net/projects/zeoslib/ 2:解压文件到文件安装目录下:C:\Program Files\Embar ...

  4. Overlapping generations model

    I.6 Overlapping generations 世代被分离开,世代不重复一定满足哈代公式的条件,但是现实情况远没有这么简单(因为会世代重叠,即亲代死去同时一个亲代在不同时间都有可能产生子代,因 ...

  5. Uber坚持不盈利,葫芦里到底卖的是什么药?

    近日,据媒体报道在美国科罗拉多州阿斯彭举办的<财富>科技头脑风暴大会上,Uber CEO达拉·科斯罗萨西表示,Uber无需在2019年下半年上市计划实施前保持盈利状态. 首先要明确一点的是 ...

  6. oracle_(第二课)监听器配置

    一. 1.首先我们得安装好oracle数据库(上一课有讲) 再来看看我们没有监听器之前的文件 文件路径:%ORACLE_HOME%/NETWORK/ADMIN 2.关闭所有防火墙,win10的要特别注 ...

  7. S5P4418开发板android源码下uboot和内核缺省文件的配置

    uboot 需要配置缺省文件,进入解压的源码目录 android,然后进入 u-boot 目录,如下图所示.如上图所示,如果是 1G 核心板,则使用“cp nsih-1G16b-4418.txt ns ...

  8. 吴裕雄--天生自然python学习笔记:python 用pygame模块加载图片

    加载图片 使用几何绘图无法画出精细的图形,所以我们可以把现成的图片加载到 Pygam e 中直接使用 . 加载图片的语法为 : 图片加载后通常会用 convert 方法加以处理, 以增加显示速度,语法 ...

  9. VBA/VB6/VBS/VB.NET/C#/Python/PowerShell都能调用的API封装库

    API函数很强大,但是声明的时候比较繁琐. 我开发的封装库,包括窗口.键盘.鼠标.消息等常用功能.用户不需要添加API函数的声明,就可以用到API的功能. 在VBA.VB6的引用对话框中引用API.t ...

  10. 虚拟环境(virtualenv)

    为什么需要虚拟环境: 到目前位置,我们所有的第三方包安装都是直接通过pip install xx的方式进行安装的,这样安装会将那个包安装到你的系统级的Python环境中.但是这样有一个问题,就是如果你 ...