图像对比度增强在计算机视觉中的应用

计算机视觉领域,对比度增强是提升图像质量、改善模型性能的关键步骤。对比度,简而言之,是指图像中不同区域之间可观察到的差异。这种差异在像素层面表现为明显的不同。对比度增强不是简单地对所有像素进行统一的亮度调整,而是根据像素之间的相对差异进行调整,使得暗像素在整个图像中更加均匀地分布。

对比度增强在天文学中尤为常见,例如,可以比较两张同一时间拍摄的月亮图像:左侧的图像对比度较低,而右侧的图像对比度较高。对比度的提高不仅使图像看起来更悦目,而且对于神经网络来说也更容易理解。回想一下计算机视觉中的一个基本原则,无论是分类、目标检测还是分割,边缘检测都是核心任务。通过对比度预处理,边缘变得更加清晰,因为邻近像素之间的差异被放大。

对比度预处理与数据增强有所不同:预处理意味着对训练集、验证集和测试集中的所有图像都应用相同的转换。而数据增强仅适用于训练集。通常,如果问题中存在对比度较低的图像,或者部分图像的对比度过于饱和,通过预处理平滑图像的对比度是有益的。处理扫描文档时,对比度通常低于理想值。在低对比度的情况下,对于光学字符识别(OCR)来说,识别微弱的字母可能具有挑战性。创建字母与背景之间的更大对比度可以产生更清晰的边缘。需要注意的是,对比度的变化不仅仅是使整个图像变暗:白色背景几乎是相等的色调。

在OCR中添加对比度是一个常见的预处理步骤。对比度预处理可以在许多开源框架中实现,例如TensorFlow中的图像对比度、PyTorch中的图像对比度预处理、FastAI中的图像对比度调整,以及scikit-image中的直方图均衡化对比度。注意:如果在单一框架中进行对比度处理,将来尝试迁移到另一个框架时可能会遇到问题,因为并非所有实现都是相同的。

在scikit-image中,文档提供了一个关于图像对比度如何影响图像属性的很好的例子。通过scikit-image文档中的直方图均衡化。对比度调整(自适应直方图均衡化,AHE)主要是将暗像素更均匀地分布在整个图像中。这个例子还引入了一个提高对比度的基本概念:局部均衡化。像自适应均衡化这样的对比度调整会考虑图像的局部部分,以防止出现中间中间图像的结果,而是将对比度变化更均匀地分布在整个图像中。

import numpy as np import matplotlib import matplotlib.pyplot as plt from skimage import data from skimage.util.dtype import dtype_range from skimage.util import img_as_ubyte from skimage import exposure from skimage.morphology import disk from skimage.filters import rank matplotlib.rcParams['font.size'] = 9 def plot_img_and_hist(image, axes, bins=256): """Plot an image along with its histogram and cumulative histogram. """ ax_img, ax_hist = axes ax_cdf = ax_hist.twinx() # Display image ax_img.imshow(image, cmap=plt.cm.gray) ax_img.set_axis_off() # Display histogram ax_hist.hist(image.ravel(), bins=bins) ax_hist.ticklabel_format(axis='y', style='scientific', scilimits=(0, 0)) ax_hist.set_xlabel('Pixel intensity') xmin, xmax = dtype_range[image.dtype.type] ax_hist.set_xlim(xmin, xmax) # Display cumulative distribution img_cdf, bins = exposure.cumulative_distribution(image, bins) ax_cdf.plot(bins, img_cdf, 'r') return ax_img, ax_hist, ax_cdf # Load an example image img = img_as_ubyte(data.moon()) # Global equalize img_rescale = exposure.equalize_hist(img) # Equalization selem = disk(30) img_eq = rank.equalize(img, selem=selem) # Display results fig = plt.figure(figsize=(8, 5)) axes = np.zeros((2, 3), dtype=np.object) axes[0, 0] = plt.subplot(2, 3, 1) axes[0, 1] = plt.subplot(2, 3, 2, sharex=axes[0, 0], sharey=axes[0, 0]) axes[0, 2] = plt.subplot(2, 3, 3, sharex=axes[0, 0], sharey=axes[0, 0]) axes[1, 0] = plt.subplot(2, 3, 4) axes[1, 1] = plt.subplot(2, 3, 5) axes[1, 2] = plt.subplot(2, 3, 6) ax_img, ax_hist, ax_cdf = plot_img_and_hist(img, axes[:, 0]) ax_img.set_title('Low contrast image') ax_hist.set_ylabel('Number of pixels') ax_img, ax_hist, ax_cdf = plot_img_and_hist(img_rescale, axes[:, 1]) ax_img.set_title('Global equalise') ax_img, ax_hist, ax_cdf = plot_img_and_hist(img_eq, axes[:, 2]) ax_img.set_title('Local equalize') ax_cdf.set_ylabel('Fraction of total intensity') # prevent overlap of y-axis labels fig.tight_layout() plt.show()
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485