文章起源 | 恒源云社区(恒源智享云)
原文地址 | 直方图
原文作者 | instter
学习指标
- 把握图像的直方图计算和显示
- 理解掩膜的利用
- 相熟直方图均衡化,理解自适应均衡化
1 灰度直方图
1.1 原理
直方图是对数据进行统计的一种办法,并且将统计值组织到一系列实现定义好的 bin 当中。其中,bin 为直方图中常常用到的一个概念,能够译为“直条”或“组距”,其数值是从数据中计算出的特色统计量,这些数据能够是诸如 梯度、方向、色调 或任何其余特色。
图像直方图(Image Histogram)是用以示意数字图像中亮度散布的直方图,标绘了图像中每个亮度值的像素个数。这种直方图中,横坐标的左侧为较暗的区域,而右侧为较亮的区域。因而一张较暗图片的直方图中的数据多集中于左侧和两头局部,而整体亮堂、只有大量暗影的图像则相同。留神:直方图是依据灰度图进行绘制的,而不是彩色图像。假如有一张图像的信息(灰度值 0 – 255,已知数字的范畴蕴含 256 个值,于是能够按肯定法则将这个范畴宰割成子区域(也就是 bins)。如:
\(\left[0,255\right] = \left[0,15\right]\bigcup\left[16,30\right]\cdots\bigcup\left[240,255\right] \)
而后再统计每一个 bin(i) 的像素数目。能够失去下图(其中 x 轴示意 bin,y 轴示意各个 bin 中的像素个数):
直方图的一些术语和细节:
- dims:须要统计的特色数目。在上例中,dims = 1,因为仅仅统计了灰度值。
- bins:每个特色空间子区段的数目,可译为“直条”或“组距”,在上例中,bins = 16。
- range:要统计特色的取值范畴。在上例中,range = [0, 255]。
直方图的意义:
- 直方图是图像中像素强度散布的图形表达方式。
- 它统计了每一个强度值所具备的像素个数。
- 不同的图像的直方图可能是雷同的
1.2 直方图的计算和绘制
咱们应用 OpenCV 中的办法统计直方图,并应用 matplotlib 将其绘制进去。
API:
cv2.calcHist(images,channels,mask,histSize,ranges[,hist[,accumulate]])
参数:
- images: 原图像。当传入函数时应该用中括号 [] 括起来,例如:[img]。
- channels: 如果输出图像是灰度图,它的值就是 [0];如果是彩色图像的话,传入的参数能够是 [0],[1],[2] 它们别离对应着通道 B,G,R。
- mask: 掩模图像。要统计整幅图像的直方图就把它设为 None。然而如果你想统计图像某一部分的直方图的话,你就须要制作一个掩模图像,并应用它。(后边有例子)
- histSize:BIN 的数目。也应该用中括号括起来,例如:[256]。
- ranges: 像素值范畴,通常为 [0,256]
示例:
如下图,绘制相应的直方图
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
# 1 间接以灰度图的形式读入
img = cv.imread('./image/cat.jpeg',0)
# 2 统计灰度图
histr = cv.calcHist([img],[0],None,[256],[0,256])
# 3 绘制灰度图
plt.figure(figsize=(10,6),dpi=100)
plt.plot(histr)
plt.grid()
plt.show()
1.3 掩膜的利用
掩膜是用选定的图像、图形或物体,对要解决的图像进行遮挡,来管制图像 解决的区域。
在 数字图像处理
中,咱们通常应用二维矩阵数组进行掩膜。== 掩膜是由 0 和 1 组成一个二进制图像,利用该掩膜图像要解决的图像进行掩膜,其中 1 值的区域被解决,0 值区域被屏蔽,不会解决。
掩膜的主要用途是:
- 提取感兴趣区域:用事后制作的感兴趣区掩模与待处理图像进行”与“操作,失去感兴趣区图像,感兴趣区内图像值放弃不变,而区外图像值都为 0。
- 屏蔽作用:用掩模对图像上某些区域作屏蔽,使其不加入解决或不加入解决参数的计算,或仅对屏蔽区作解决或统计。
- 构造特征提取:用相似性变量或图像匹配办法检测和提取图像中与掩模类似的结构特征。
- 非凡形态图像制作
掩膜在遥感影像解决中应用较多,当提取路线或者河流,或者屋宇时,通过一个掩膜矩阵来对图像进行像素过滤,而后将咱们须要的地物或者标记突出显示进去。
咱们应用 cv.calcHist()
来查找残缺图像的直方图。如果要查找图像某些区域的直方图,该怎么办?只需在要查找直方图的区域上创立一个红色的掩膜图像,否则创立彩色,而后将其作为掩码 mask 传递即可。
示例:
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
# 1. 间接以灰度图的形式读入
img = cv.imread('./image/cat.jpeg',0)
# 2. 创立蒙版
mask = np.zeros(img.shape[:2], np.uint8)
mask[400:650, 200:500] = 255
# 3. 掩模
masked_img = cv.bitwise_and(img,img,mask = mask)
# 4. 统计掩膜后图像的灰度图
mask_histr = cv.calcHist([img],[0],mask,[256],[1,256])
# 5. 图像展现
fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,8))
axes[0,0].imshow(img,cmap=plt.cm.gray)
axes[0,0].set_title("原图")
axes[0,1].imshow(mask,cmap=plt.cm.gray)
axes[0,1].set_title("蒙版数据")
axes[1,0].imshow(masked_img,cmap=plt.cm.gray)
axes[1,0].set_title("掩膜后数据")
axes[1,1].plot(mask_histr)
axes[1,1].grid()
axes[1,1].set_title("灰度直方图")
plt.show()
2 直方图均衡化
2.1 原理与利用
设想一下,如果一副图像中的大多数像素点的像素值都集中在某一个小的灰度值值范畴之内会怎么呢?如果一幅图像整体很亮,那所有的像素值的取值个数应该都会很高。所以应该把它的直方图做一个横向拉伸(如下图),就能够扩充图像像素值的散布范畴,进步图像的对比度,这就是直方图均衡化要做的事件。
“直方图均衡化”是把原始图像的灰度直方图从比拟集中的某个灰度区间变成在更宽泛灰度范畴内的散布。直方图均衡化就是对图像进行非线性拉伸,重新分配图像像素值,使肯定灰度范畴内的像素数量大致相同。
这种办法进步图像整体的对比度,特地是有用数据的像素值散布比拟靠近时,在 X 光图像中应用宽泛,能够进步骨架构造的显示,另外在曝光适度或有余的图像中能够更好的突出细节。
应用 opencv 进行直方图统计时,应用的是:
API:
dst = cv.equalizeHist(img)
参数:
- img: 灰度图像
返回: - dst : 均衡化后的后果
示例
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
# 1. 间接以灰度图的形式读入
img = cv.imread('./image/cat.jpeg',0)
# 2. 均衡化解决
dst = cv.equalizeHist(img)
# 3. 后果展现
fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img,cmap=plt.cm.gray)
axes[0].set_title("原图")
axes[1].imshow(dst,cmap=plt.cm.gray)
axes[1].set_title("均衡化后后果")
plt.show()
2.2 自适应的直方图均衡化
上述的直方图平衡,咱们思考的是图像的全局对比度。确实在进行完直方图均衡化之后,图片背景的对比度被扭转了,在猫腿这里太暗,咱们失落了很多信息,所以在许多状况下,这样做的成果并不好。如下图所示,比照下两幅图像中雕像的画面,因为太亮咱们失落了很多信息。
为了解决这个问题,须要应用自适应的直方图均衡化。此时,整幅图像会被分成很多小块,这些小块被称为“tiles”(在 OpenCV 中 tiles 的 大小默认是 8×8),而后再对每一个小块别离进行直方图均衡化。所以在每一个的区域中,直方图会集中在某一个小的区域中)。如果有噪声的话,噪声会被放大。为了防止这种状况的呈现要应用对比度限度。对于每个小块来说,如果直方图中的 bin 超过对比度的下限的话,就把 其中的像素点平均扩散到其余 bins 中,而后在进行直方图均衡化。
最初,为了 去除每一个小块之间的边界,再应用双线性差值,对每一小块进行拼接。
API:
cv.createCLAHE(clipLimit, tileGridSize)
参数:
- clipLimit: 对比度限度,默认是 40
- tileGridSize: 分块的大小,默认为 8 *88∗8
示例:
import numpy as np
import cv2 as cv
# 1. 以灰度图模式读取图像
img = cv.imread('./image/cat.jpeg',0)
# 2. 创立一个自适应均衡化的对象,并利用于图像
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
cl1 = clahe.apply(img)
# 3. 图像展现
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img,cmap=plt.cm.gray)
axes[0].set_title("原图")
axes[1].imshow(cl1,cmap=plt.cm.gray)
axes[1].set_title("自适应均衡化后的后果")
plt.show()
总结
-
灰度直方图:
— 直方图是图像中像素强度散布的图形表达方式。
— 它统计了每一个强度值所具备的像素个数。
– 不同的图像的直方图可能是雷同的cv.calcHist(images,channels,mask,histSize,ranges [,hist [,accumulate]])
- 掩膜
— 创立蒙版,透过 mask 进行传递,可获取感兴趣区域的直方图 -
直方图均衡化:加强图像对比度的一种办法
cv.equalizeHist(): 输出是灰度图像,输入是直方图平衡图像
-
自适应的直方图平衡
— 将整幅图像分成很多小块,而后再对每一个小块别离进行直方图均衡化,最初进行拼接clahe = cv.createCLAHE(clipLimit, tileGridSize)
instter 曾经分享了好几篇笔记,感兴趣的童鞋,也能够温故之前的帖子~
1、联邦学习
2、卷积神经网络的工作原理
3、opencv
4、几何变换