用Skimage学习数字图像处理(008):图像空域增强之灰度级点运算

本文介绍了图像空域增强的基本概念,重点讲解了Skimage库中的灰度级点运算技术,如反色变换、对数变换、幂次变换(伽马校正)、Sigmoid变换和对比度拉伸,以及如何使用这些技术提升图像视觉质量。
摘要由CSDN通过智能技术生成

从本节开始,开始介绍图像空域增强的内容。本节为上篇,介绍一类基础图像空域增强技术:面向灰度级的点运算。

通过本节的学习,读者将初步了解图像空域增强中常用的灰度级点运算,比如Gamma校正幂次变换对比度拉伸反色变换等等。这一部分主要用到了Skimage中的exposure模块。

目录

5.1 概述

5.2 基于点运算的图像增强

5.2.1 反色变换(图像反转)

5.2.2 对数(反对数)变换

5.2.3 幂次变换(Gamma变换)

5.2.4 Sigmoid变换

5.2.5 灰度级拉伸变换

5.2.6 综合实例


5.1 概述

从本节开始,进入到图像处理中的一个重要而基础的领域:图像空域增强Spatial Enhancement。该领域是伴随着数字图像处理学科的开始涌现出的一个基本问题。

图像增强的目的是提高图像的视觉质量,也可以是使特定的特征显得更加突出。这类技术更多的是从主观感受出发,通常不会涉及图像质量退化模型,这点是与后面章节讨论的图像复原最明显的区别。从处理结果出发,典型的图像增强技术包括对比度增强图像平滑锐化等。

下图所示为labview软件提供的各类经典图像增强技术的分类图,同样适用于本教程。

(经典图像增强技术分类,来自labview介绍文档)

参照上图,简要介绍经典图像增强技术的分类。

  • 按照作用域不同,分为空域增强频域增强两类,两者比较,空域增强占主导地位;
  • 频域增强可按照功能进行划分(如低通、高通、带阻等),也可按照频域类型划分(如傅里叶域、小波域等);
  • 空域增强技术,按照是否使用邻域信息,可分为点运算邻域滤波,点运算有可进一步分为灰度变换直方图变换等。

各种增强技术有自身的特点,有的技术实现简单,但性能单一,有的技术功能强大,但计算复杂。我们将参考上图的分类方式,逐一介绍几种有代表性技术基于Skimage的具体实现。至于各类技术的工作原理,不再详细介绍,请各位参考相关文献。

5.2 基于点运算的图像增强

点运算是对输入图像的各个像素应用变换函数T,对应输出图像的像素点为g(x,y),上述过程可表示为g(x,y)=T\left [ f(x,y) \right ],该变换用不到位置信息(x,y),因此该变换可改写为s=T(r),其中r和s分别代表输入图像灰度值和对应的输出图像灰度值。 因此,各种点运算的区别在于T的定义方式的不同。

按照灰度映射函数的性质,灰度变换可以分为线性变换、分段线性和非线性变换非线性变换中对数变换、指数变换和幂律变换(n次幂、n次根)最为常用。

5.2.1 反色变换(图像反转)

图像反色(Invert)变换,又称为图像反转,是将深色像素点变浅色,浅色像素点变深色。广义的反色变换也可以应用于彩色图像,即对所有像素点取补。

图像的反转处理可以增强暗色区域中的白色或灰色细节,对应的变换定义为:s=T(r)=255-r

如果待处理图像的灰度级范围是[0,1],则反色变换为s=T(r)=1-r

在Skimage中,使用util.invert直接完成反色处理。

invert函数完成反色处理

看一下warp函数的声明:

skimage.util.invert(image, signed_float)

部分参数说明

  • image:输入图像。
  • signed_float:实型标志,默认为False。如果设为True,则范围为[-1,1],否则,根据图像数据类型来确定范围。

返回值

  • inverted:变换后的图像,与输入图像相同。

对于不同数据类型的图像,反色处理方式略有不同:

  • 无符号整型:用灰度值的理论最大值减去当前灰度值,对于[0,255]范围内的的灰度或彩色图像,s=255-r。
  • 有符号整型:此时图像灰度值取值范围是[-128,127],对应的反色处理是s=r*(-1)-1,但这类情况很少用到。
  • 实型:如果signed_float标志位是True,则s=1-r,否则,s=r*(-1)。

给出一段基于invert函数的代码,读者可自行确认处理结果。

img1 = np.array([[100,  0, 200], [  0, 50,   0], [ 30,  0, 255]], np.uint8)
invert(img1)
print(img1)

img2 = np.array([[ -2, 0, -128], [127, 0,    5]], np.int8)
invert(img2)
print(img2)

img3 = np.array([[ 0., 1., 0.5, 0.75]])
invert(img3)
print(img3)

img4 = np.array([[ 0., 1., -1., -0.25]])
invert(img4, signed_float=True)
print(img4)

四种反色处理输出结果为:

array([[155, 255,  55], [255, 205, 255],[225, 255,   0]], dtype=uint8)

array([[1,   -1,  127], [-128,   -1,   -6]], dtype=int8)

array([[1.  , 0.  , 0.5 , 0.25]])

array([[-0.  , -1.  ,  1.  ,  0.25]])

5.2.2 对数(反对数)变换

图像的对数变换可以增强暗色区域中的白色或灰色细节,对应的变换定义为:s=T(r)=c\cdot log_2(r+1)

常数𝑐用来调整放缩倍数,“+1”操作是为了避免𝑟=0的情况,注意,对数变换是以2为底的,不是e或10。

 在Skimage中,使用adjust_gamma函数完成反色处理。

adjust_gamma函数用于完成对数/反对数变换

看一下adjust_gamma函数的声明:

skimage.exposure.adjust_log(image, gain, inv)

部分参数说明

  • image:输入图像。
  • gain:增益值,对应于c,默认值为1。
  • inv:操作标志位,默认为False,对应着对数比那换。如果设为True,则为反对数变换。

返回值

  • out:对数变换后的图像。
 

以下是有关对数变换功能的说明,可参考:

  • 对数曲线在像素值较低的区域斜率大,在像素值较高的区域斜率小。对数变换将输入中范围较窄的低灰度值映射为范围较宽的灰度级,输入中的高灰度值则被映射为范围较窄的灰度级。对数变换后,较暗区域的对比度提升,可以增强图像的暗部细节。
  • 对数变换实现了扩展低灰度值而压缩高灰度值的效果,广泛应用于频谱图像的显示中。对数变换的典型应用是傅立叶频谱的动态范围很宽,直接显示时受显示设备动态范围的限制而丢失大量的暗部细节;使用对数变换将图像的动态范围进行非线性压缩后,就可以清晰地显示。

5.2.3 幂次变换(Gamma变换)

图像的幂次变换(Power Law),又称为Gamma变换,可以提升暗部细节,对发白(曝光过度)或过暗(曝光不足)的图片进行矫正。

幂次变换定义为:s=T(r)=c\cdot r^{\gamma}

常数𝑐用来调整放缩倍数,幂次𝛾值的大小用于调整变换的功能,详情如下:

  • 当 𝛾>1时,压缩低灰度级,扩展高灰度级,图像整体变暗;
  • 当 𝛾<1时,扩展低灰度级,压缩高灰度级,图像整体变亮;

(幂次变换函数说明,改编自参考文献1)

在Skimage中,使用adjust_gamma函数完成反色处理。

adjust_gamma函数用于完成幂次变换

看一下warp函数的声明:

skimage.exposure.adjust_gamma(image, gamma, gain)

部分参数说明

  • image:输入图像。
  • gamma:非负实数,默认值为1.0,不同的gamma值,对应不同功能,见前面的注释。
  • gain:增益值,默认值为1.0。

返回值

  • inverted变换后的图像,与输入图像相同。

幂次变换通过非线性变换对人类视觉特性进行补偿,最大化地利用有效的灰度级带宽。很多拍摄、显示、打印设备的亮度曲线都符合幂律曲线,因此幂次变换广泛应用于各种设备显示效果的调校,称为伽马校正。

5.2.4 Sigmoid变换

无论是对数(反对数)变换,还是幂次变换,当参数确定后,都只能压缩(或拉伸)低灰度级,不能完成中间区域灰度级的拉伸。基于这种情况,Skimage在exposure模块中引入了sigmoid函数,完成上述功能。

标准的Sigmoid函数定义为:sigmoid(x)=\frac{1}{1+e^{-x}},但该函数是关于x=0对称的。假设图像灰度级范围归一化到[0,1]之间,则一种基于Sigmoid函数的灰度级拉伸函数可定义为:

sigmoid(x)=\frac{1}{1+e^{c(0.5-x)}}

式中,c为增益值,用于控制变换函数的形状。

SKimage通过adjust_sigmoid函数完成相应的变换。

adjust_sigmoid函数用于完成Sigmoid变换

看一下warp函数的声明:

skimage.exposure.adjust_sigmoid(image, cutoff, gain, inv)

部分参数说明

  • image:输入图像。
  • cutoff:对应水平方向上灰度值的偏移量,默认值为0.5。
  • gain:增益值,用于控制sigmoid函数的变化快慢,默认值为10.0。
  • inv:操作标志位,默认为False,对应着正Sigmoid变换;如果设为True,则为负Sigmoid变换(注意,不是逆变换)。

返回值

  • out:Sigmoid变换后的图像。

5.2.5 灰度级拉伸变换

前面介绍的各种灰度级点运算中,除了反色变换,其他都可归为非线性变换。Skimage还提供了一种简单有效的分段线性变换函数,完成常用的灰度级拉伸功能。

SKimage通过rescale_intensity函数完成相应的变换。

adjust_sigmoid函数用于完成Sigmoid变换

看一下warp函数的声明:

skimage.exposure.rescale_intensity(image, in_range, out_range)

部分参数说明

  • image:输入图像。
  • in_range:输入图像范围[in_min, in_max],有四种设置方式,参考后面。
  • out_range:输出图像显示范围[out_min, in_out],参数设置方式如下:
  1. 'image':Use image min/max as the intensity range.

  2. 'dtype': Use min/max of the image’s dtype as the intensity range.

  3. dtype-name:Use intensity range based on desired dtype. Must be valid key in DTYPE_RANGE.

  4. 2-tuple:Use range_values as explicit min/max intensitie

返回值

  • out灰度级拉伸变换后的图像。

有如下语句:

rescale_intensity(image, in_range=(in_min, in_max), out_range=(out_min, out_max))

该函数完成的功能是将原图像像素值先裁剪到 in_range 范围内(即将小于in_min的灰度级都赋值为in_min, 大于in_max的灰度值, 赋值in_max),再进行归一化处理,即(image-in_min) / in_max - in_min) 后, 然后再放大至out_range 区间内[out_min, out_max]。一般out_range设置为[0,255]。

经过上述步骤处理之后,原图像小于in_min灰度值会被设置为out_min,大于in_max的灰度值会被设置为out_max,[in_min, in_max]之间的灰度值,会被线性拉伸至[out_min, out_max]范围内。

5.2.6 综合实例

以下是改编自官方文档的实例,分别完成对数变换、幂次变换、Sigmoid变换和线性拉伸。(此例还需要补充后面两种变换的代码

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

from skimage import data, img_as_float
from skimage import exposure

# Load an example image
img = data.moon()

# Gamma
gamma_corrected = exposure.adjust_gamma(img, 2)

# Logarithmic
logarithmic_corrected = exposure.adjust_log(img, 1)

# Display results
fig = plt.figure(figsize=(8, 5))
axes = np.zeros((2, 3), dtype=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])

ax_img, ax_hist, ax_cdf = plot_img_and_hist(img, axes[:, 0])
ax_img.set_title('Low contrast image')

ax_img, ax_hist, ax_cdf = plot_img_and_hist(gamma_corrected, axes[:, 1])
ax_img.set_title('Gamma correction')

ax_img, ax_hist, ax_cdf = plot_img_and_hist(logarithmic_corrected, axes[:, 2])
ax_img.set_title('Logarithmic correction')

# prevent overlap of y-axis labels
fig.tight_layout()
plt.show()

上图从左至右分别是:原图、对数变换结果图、幂次变换结果图。由处理及过可见,由于𝛾>1,经幂次变换后,低灰度级被压缩,图像整体变暗;与之相反,经对数变换后,低灰度级被扩展,图像整体变亮。

(本节初稿完成时间:2024-02-11)

(欢迎对DIP+python算法开发感兴趣的初学者,尤其是相关专业本科和低年级研究生关注,本专栏完将持续更新,总篇数不会少于50篇,每篇不会少于5000字,专栏完成之前(估计至少半年)完全免费阅读,敬请关注)

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值