(一)图像直方图

图像的构成是有像素点构成的,每个像素点的值代表着该点的颜色(灰度图或者彩色图)。所谓直方图就是对图像的中的这些像素点的值进行统计,得到一个统一的整体的灰度概念。直方图的好处就在于可以清晰了解图像的整体灰度分布,这对于后面依据直方图处理图像来说至关重要。

一般情况下直方图都是灰度图像,直方图x轴是灰度值(一般0~255),y轴就是图像中每一个灰度级对应的像素点的个数。

那么如何获得图像的直方图?首先来了解绘制直方图需要的一些量:灰度级,正常情况下就是0-255共256个灰度级,从最黑一直到最亮(白)(也有可能统计其中的某部分灰度范围),那么每一个灰度级对应一个数来储存该灰度对应的点数目。也就是说直方图其实就是一个1*m(灰度级)的一个数组而已。但是有的时候我们不希望一个一个灰度的递增,比如现在我想15个灰度一起作为一个灰度级来花直方图,这个时候我们可能只需要1*(m/15)这样一个数组就够了。那么这里的15就是直方图的间隔宽度了。

Opencv给我们提供的函数是cv2.calcHist(),该函数有5个参数:

image输入图像,传入时应该用中括号[]括起来
channels::传入图像的通道,如果是灰度图像,那就不用说了,只有一个通道,值为0,如果是彩色图像(有3个通道),那么值为0,1,2,中选择一个,对应着BGR各个通道。这个值也得用[]传入。
mask:掩膜图像。如果统计整幅图,那么为none。主要是如果要统计部分图的直方图,就得构造相应的炎掩膜来计算。
histSize:灰度级的个数,需要中括号,比如[256]
ranges:像素值的范围,通常[0,256],有的图像如果不是0-256,比如说你来回各种变换导致像素值负值、很大,则需要调整后才可以。
除此之外,强大的numpy也有函数用于统计直方图的,通用的一个函数np.histogram,还有一个函数是np.bincount()(用于以为统计直方图,速度更快)。这三个方式的传入参数基本上差不多,不同的是opencv自带的需要中括号括起来。
对于直方图的显示也是比较简单的,直接plt.plot()就可以。一个实例如下:

 import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('test.jpg', 0) # 直接读为灰度图像 # opencv方法读取-cv2.calcHist(速度最快)
# 图像,通道[0]-灰度图,掩膜-无,灰度级,像素范围
hist_cv = cv2.calcHist([img], [0], None, [256], [0, 256]) # numpy方法读取-np.histogram()
hist_np, bins = np.histogram(img.ravel(), 256, [0, 256]) # numpy的另一种方法读取-np.bincount()(速度=10倍法2)
hist_np2 = np.bincount(img.ravel(), minlength=256) plt.subplot(221), plt.imshow(img, 'gray')
plt.subplot(222), plt.plot(hist_cv)
plt.subplot(223), plt.plot(hist_np)
plt.subplot(224),plt.plot(hist_np2)
plt.show()

执行结果:

现在来考虑opencv的直方图函数中掩膜的使用,这个掩膜就是一个区域大小,表示你接下来的直方图统计就是这个区域的像素统计。一个例子如下:

 import cv2
import numpy as np
import matplotlib.pyplot as plt img = cv2.imread('test.jpg', 0) # 直接读为灰度图像
mask = np.zeros(img.shape[:2], np.uint8)
mask[100:200, 100:200] = 255
masked_img = cv2.bitwise_and(img, img, mask=mask) # opencv方法读取-cv2.calcHist(速度最快)
# 图像,通道[0]-灰度图,掩膜-无,灰度级,像素范围
hist_full = cv2.calcHist([img], [0], None, [256], [0, 256]) hist_mask = cv2.calcHist([img], [0], mask, [256], [0, 256]) plt.subplot(221), plt.imshow(img, 'gray')
plt.subplot(222), plt.imshow(mask, 'gray')
plt.subplot(223), plt.imshow(masked_img, 'gray')
plt.subplot(224), plt.plot(hist_full), plt.plot(hist_mask)
plt.show()

执行结果:

(二)直方图均衡化

图像的直方图是对图像对比度效果上的一种处理,旨在使得图像整体效果均匀,黑与白之间的各个像素级之间的点更均匀一点。
直方图均衡化只要包括三个步骤:

1、统计直方图中每个灰度级出现的次数;
2、计算累计归一化直方图;
3、重新计算像素点的像素值;
关于原理的详细部分给一个参考:

直方图均衡化原理

百度百科的解释也很棒

http://baike.baidu.com/link?url=RUjahehgkTMDGKwAEyMsHyeMyWWTw9a0KUx2CzLbXtxdZyoF6zqDbJsfEffUQYAwvr7kD9p6cbOxJGYGk1nkZq

在opencv有专门函数对直方图进行均衡化使用的函数就是cv2.equalizeHist().一个实例如:

import cv2
import matplotlib.pyplot as plt img = cv2.imread('flower.jpg',0) #直接读为灰度图像
res = cv2.equalizeHist(img) plt.subplot(121),plt.imshow(img,'gray')
plt.subplot(122),plt.imshow(res,'gray')

上述的直方图均衡化可以可能到是一种全局意义上的均衡化,但是有的时候这种操作并不是很好,会把某些不该调整的部分给调整了。Opencv中还有一种直方图均衡化,它是一种局部局部来的均衡化,也就是是说把整个图像分成许多小块(比如按10*10作为一个小块),那么对每个小块进行均衡化。这种方法主要对于图像直方图不是那么单一的(比如存在多峰情况)图像比较实用。Opencv中将这种方法称之为CLAHE,使用到的函数就是cv2.createCLAHE(),一个实例如下:

import cv2
import matplotlib.pyplot as plt img = cv2.imread('flower.jpg',0) #直接读为灰度图像
clahe = cv2.createCLAHE(clipLimit=2,tileGridSize=(10,10))
cl1 = clahe.apply(img) plt.subplot(121),plt.imshow(img,'gray')
plt.subplot(122),plt.imshow(cl1,'gray')

可以看到,相对于全局的直方图均衡化,这个局部的均衡化似乎得到的效果更自然一点。
————————————————
版权声明:本文为CSDN博主「on2way」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/on2way/article/details/46881599

1

opencv2——直方图5的更多相关文章

  1. opencv2 直方图之calchist函数使用(转)

    OpenCV提供了calcHist函数来计算图像直方图. 其中C++的函数原型如下:void calcHist(const Mat* arrays, int narrays, const int* c ...

  2. OpenCV2:直方图

    一.简介 在一个单通道的灰度图像中,每个像素的值介于0(黑色)~255(白色)之间,灰色图像的直方图有256个条目(或称为容器)

  3. OpenCV2+入门系列(四):计算图像的直方图,平均灰度,灰度方差

    本篇懒得排版,直接在网页html编辑器编辑 在图像处理时,我们常常需要求出图像的直方图.灰度平均值.灰度的方差,这里给出一个opencv2+自带程序,实现这些功能. 直方图 对于直方图,使用cv::c ...

  4. opencv2对于读书笔记——背投影图像的直方图来检测待处理的内容

    一些小的概念 1.直方图是图像内容的一个重要特性. 2.假设一幅图像的区域中显示的是一种独特的纹理或是一个独特的物体,那么这个区域的直方图能够看作是一个概率函数,它给出的是某个像素属于该纹理或物体的概 ...

  5. OpenCV2马拉松第10圈——直方图反向投影(back project)

    收入囊中 灰度图像的反向投影 彩色图像的反向投影 利用反向投影做object detect 葵花宝典 什么是反向投影?事实上没有那么高大上! 在上一篇博文学到,图像能够获得自己的灰度直方图. 反向投影 ...

  6. OpenCV2马拉松第12圈——直方图比較

    收入囊中 使用4种不同的方法进行直方图比較 葵花宝典 要比較两个直方图, 首先必需要选择一个衡量直方图相似度的对照标准.也就是先说明要在哪个方面做对照. 我们能够想出非常多办法,OpenCV採用了下面 ...

  7. OpenCV2马拉松第9圈——再谈对照度(对照度拉伸,直方图均衡化)

    收入囊中 lookup table 对照度拉伸 直方图均衡化 葵花宝典 lookup table是什么东西呢? 举个样例,假设你想把图像颠倒一下,f[i] = 255-f[i],你会怎么做? for( ...

  8. opencv2反投影直方图以检測特定的图像内容

    #ifndef HISTOGRAM_H_ #define HISTOGRAM_H_ #include<opencv2/core/core.hpp> #include<opencv2/ ...

  9. OpenCV2:Mat属性type,depth,step

    在OpenCV2中Mat类无疑使占据着核心地位的,前段时间初学OpenCV2时对Mat类有了个初步的了解,见OpenCV2:Mat初学.这几天试着用OpenCV2实现了图像缩小的两种算法:基于等间隔采 ...

随机推荐

  1. head 显示文件头部内容

    1. 命令功能 head 默认显示文件前10行内容. 2.语法格式 head option file 参数说明 参数 参数说明 -n 指定显示行数 -c 指定显示的字节数 -v 总是显示文件名的文件头 ...

  2. Java8 的一些新特性的学习理解

    近期在学习队列相关的一些知识,在学习过程中发现Iterable<T>接口中新增了两个新的方法,出于好奇,就想知道这是什么东东,干什么用的.俗话说:实践出真知,所以就有了以下反复的测试. 先 ...

  3. tpcc-mysql测试mysql5.6 (EXT4文件系统)

    操作系统版本:CentOS release 6.5 (Final)  2.6.32-431.el6.x86_64 #1 内存:32G CPU:Intel(R) Xeon(R) CPU E5-2450 ...

  4. thinkphp 关联

    原理:https://www.kancloud.cn/laowu199/e_dev/448632 示例数据库 hasOne:有一个,加上主谓语应该是 ,A 有一个 BhasMany:有很多,A 有很多 ...

  5. 前端每日实战:86# 视频演示如何用纯 CSS 创作一个方块旋转动画

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/gjgyWm 可交互视频 此视频是可 ...

  6. QTimer不能同时使用两个,用QTimerEvent (QT)

    最近写程序的时候有个界面想定两个QTimer定时器,不同时间干不同的事: QTimer *timer1 = new QTimer(this); QTimer *timer2 = new QTimer( ...

  7. java匿名内部类 (转载)

    匿名内部类也就是没有名字的内部类 正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写 但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口 实例1:不使用匿名内部类来实现抽象 ...

  8. C++创建对象时什么时候用*,什么时候不用*

    用*, 表示创建的是一个指针对象,而指针的创建,必须初始化,C++中用new关键字开辟内存. 另外指针对象访问成员变量用-> , 非指针用. 就这么个原则 但是指针也可以不用-> 例如 ( ...

  9. c# 如何更改 WebBrowser所加载的 HTML元素(隐藏滚动条),并按照修改后的来呈现

    如何更改 WebBrowser所加载的 HTML元素 方法1:在网页加载完毕后的事件里面添加代码,我这里只是修改网页不出现滚动条,因为滚动条我重写了. #region (private) 网页加载完成 ...

  10. 20180813-Java 重写(Override)与重载(Overload)

    Java 重写(Override)与重载(Overload) class Animal{ public void move(){ System.out.println("动物可以移动&quo ...