一. 灰度直方图
令,其中
,表示一幅L级灰度数字图像f(x,y)的灰度。f的非归一化直方图定义为:
,
式中,是f中灰度为
的像素的数量,并且细分的灰度级称为直方图容器。
f的归一化直方图定义为:
式中,M和N分别是一幅数字图像的行列数。在大多数情况下,处理的都是归一化直方图。对k所有值,的和总是1,
的分量是对图像中出现的灰度级的概率估计。
在matplotlib中有绘制直方图的函数:plt.hist(),可以直接统计计算并绘制颜色直方图。
plt.figure(figsize=(5,4), dpi=200)
plt.rcParams["font.family"] = "Times New Roman"
plt.hist(image_gray.ravel(),256,[0,256], color='gray')
plt.title('Gray Histograms')
plt.show()

如果是三通道,则循环遍历各通道,依次绘制每个通道的颜色直方图。
color = ('b','g','r')
plt.figure(figsize=(5,4), dpi=200)
for i,col in enumerate(color):
hist = cv2.calcHist([image_brg],[i],None,[256],[0,256])
plt.plot(hist,color = col)
plt.xlim([0,256])
plt.show()
plt.figure(figsize=(5,4), dpi=200)
plt.imshow(cv2.cvtColor(image_brg, cv2.COLOR_BGR2RGB))
plt.axis('off')

如果在绘制直方图的时候,需要对指定图像位置进行绘制,可以利用掩模提取目标区域再绘制直方图。
二. 直方图均衡化
直方图均衡化通常会增加图像的全局对比度,尤其是当图像由较窄的灰度(强度)值范围表示时。通过这个方法可以更好地利用整个强度范围均匀地分布在直方图上。这允许局部对比度较低的区域获得较高的对比度。

直方图均衡化在背景和前景都很亮或都很暗的图像中很有用。特别是,该方法可以在 X 射线图像中更好地观察骨骼结构,并在曝光过度或曝光不足的照片中获得更好的细节。该方法的一个关键优点是,它是一种相当简单的技术,适用于输入图像和可逆运算符。所以从理论上讲,如果直方图均衡函数是已知的,那么原始直方图就可以恢复。
图像的灰度可视为区间[0,L-1]内的随机变量。令和
表示两幅不同图像中灰度值r和s的PDF,若已知
和
,且
在定义域范围内是连续可微的,则变换后的变量s的PDF是:
可见,输出灰度变量的PDF是由输入灰度的PDF和所用的变换函数确定。
图像处理中的一个很重要的变换函数:
式中,w是一个假积分变量,右侧的积分是随机变量r的累积分布函数(CDF)。
因此,输出灰度的PDF:
可见,是均匀分布概率密度函数。
opencv中提供了库函数进行图像的直方图均衡化
equ_image = cv2.equalizeHist(image_gray)
plt.figure(figsize=(20,5), dpi=200)
plt.rcParams["font.family"] = "Times New Roman"
plt.subplots_adjust(wspace=0.03)
plt.subplot(1, 4, 1)
plt.imshow(cv2.cvtColor(image_gray, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.title('original image', fontsize=18)
plt.subplot(1, 4, 2)
plt.hist(image_gray.ravel(), 256, [0, 256])
plt.tick_params(labelbottom=False, labelleft=False, direction='in')
plt.axis('on')
plt.subplot(1, 4, 3)
plt.imshow(cv2.cvtColor(equ_image, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.title('equalized image', fontsize=18)
plt.subplot(1, 4, 4)
plt.hist(equ_image.ravel(), 256, [0, 256])
plt.tick_params(labelbottom=False, labelleft=False, direction='in')
plt.axis('on')

三. 直方图匹配
在有些应用中使用直方图均衡化是不合适的,有时候可以规定待处理图像的直方图形状是有用的。这种用于生成具有规定直方图的方法称为直方图匹配或直方图规定化。
假设连续灰度r和z,r和z分别是输入图像和输出图像的灰度级,其PDF函数是和
,
是规定化的PDF。
对于连续形式:
令s是一个具有如下性质的随机变量:
再定义一个关于变量z的函数G:
所以:
得到具有规定PDF的图像步骤:
- 由输入图像得到
;
- 由
得到
;
- 计算反变换
,s到z的映射;
- 由
得到均匀化的输出图像;输出图像的像素值是s,对于均衡化后的图像中的像素值为s的每个像素执行逆变换
,得到输出图像中的对应像素。使用这个变化后得到的PDF就是规定的PDF。
对于离散形式:
输入图像的变换:
对于变量z:
所以,由反变换得到规定化的:
对所有像素执行这些变换后得到的就是一个从s到z的一个映射。
def histogram_matching(source, template):
source_hist, bins = np.histogram(source.flatten(), 256, [0, 256])
template_hist, bins = np.histogram(template.flatten(), 256, [0, 256])
# 计算累积分布函数(CDF)
source_cdf = source_hist.cumsum()
template_cdf = template_hist.cumsum()
# 创建映射表
mapping = np.zeros(256, dtype=np.uint8)
template_cdf_idx = 0
for source_cdf_idx in range(256):
while template_cdf_idx < 256 and template_cdf[template_cdf_idx] < source_cdf[source_cdf_idx]:
template_cdf_idx += 1
mapping[source_cdf_idx] = template_cdf_idx
matched = cv2.LUT(source, mapping)
return matched
source_image = cv2.imread(r'D:\pythonwork\imagepro\data\Fig0011.tif', cv2.IMREAD_GRAYSCALE)
template_image = cv2.imread(r'D:\pythonwork\imagepro\data\Fig0014.tif', cv2.IMREAD_GRAYSCALE)
matched_image = histogram_matching(source_image, template_image)


1890

被折叠的 条评论
为什么被折叠?



