接下来将介绍与图像几何变换相关的内容,涉及到五种常见的图像二维几何变换:平移、镜像、旋转、错切和放缩。本节是上篇,重点介绍图像的尺寸的放缩操作,并会涉及一种基于抗混叠技术。本节约5700字。
目录
4.2.3 基于局部均值的下采样(downscale_local_mean)
4.2.4 基于局部均值的尺寸调整(resize_local_mean)
4.1 概述
图像的几何变换是指对图像的位置、大小、形状、投影进行变换,是将图像从原始平面投影到新的视平面。Skimage中的图像以多维数组(arrary)描述,几何变换本质上是将一个多维数组通过映射关系求得另一个多维数组。
几何变换可以分为等距变换、相似变换、仿射变换和投影变换。通常又把等距变换、相似变换统称为仿射变换,常见的仿射变换包括平移、旋转、缩放、翻转、错切等方法。
下面列出了各类变换的简要描述和对应的英文名称:
- 等距变换:又称为欧式变换(Euclidean Transformation)或刚体变换,图像中的长度、面积不变,典型的等距变换如平移(Translation Transformation)、旋转(Rotation Transformation)。
- 相似变换:相似变换(Similarity transformation)指的是图像中的长度比、夹角、虚圆点不变,相似变换是在等距变换的基础上进行了各项同性放缩(Isotropic Scaling Transformation)。
- 仿射变换(Affine transformation):图像中的平行关系、面积比、共线线段或平行线段的长度比、矢量的线性组合不变,仿射变换是旋转和不同性放缩(Non-inotropic Scaling)的组合,典型的仿射变换是斜切(Shear Transformation)。
- 投影变换(Projection transformation,又称“透视变换”):图像中的共点、共线、相交、相切、拐点的关系不变,投影变换是在仿射变换基础上进行的非线性缩放,典型的投影变换是透视。
4.2 图像放缩变换
常见的图像二维几何变换包括平移、镜像、旋转、错切和放缩等。其中前五种操作变换中,输出图像的每一个像素点在输入图像中都有一个具体的像素点与之对应。只有放缩操作(尤其是放大),新出现的像素点与原图像中已有的点不对应,这种不对应表现在位置和强度值两方面。
这类由低分辨率图像通过算法生成高分辨率图像的技术,在图像处理领域统称为超分辨率(Super-Resolution),简称超分。现有的超分辨率方法分为三类:基于插值的方法、基于重建的方法和基于学习的方法(即深度学习方法)。本节介绍的各种图像插值算法,都属于实现超分的经典技术。
典型的图象插值方法有:最近邻插值、双线性插值、双平方插值、双立方插值以及其他高阶方法。相关内容在DIP的教材中都有介绍,在此不在对其原理展开说明。本节将重点介绍Skimage中提供的插值方法,以及具体实现过程。
Skimage使用transform模块完成图像的几何变换功能,其中与图像放缩操作相关的函数有四个,分别是:rescale、resize、downscale_local_mean、resize_local_mean,它们的功能略有差别,下面逐一介绍。
4.2.1 比例放缩(rescale)
Skimage使用rescale函数完成按照比例放缩图像。
以下是rescale函数的声明:
rescale(image, scale, order, mode, cval, clip, preserve_range, anti_aliasing, anti_aliasing_sigma, channel_axis)
部分参数说明:
- image:输入图像:ndarray型,可以是单通道/3/4通道图像。
scale:放缩因子,实型(或实型元组)单独设置的放缩因子数值。
order:插值方法的序号(0-5),对应样条插值函数插值序号,可选项。如果图像数据是bool型(对应二值图情况),则默认值为0;否则设为1。
mode:边界延拓方式,包括(常值延拓)‘constant’, (边界延拓)‘edge’, (对称延拓)‘symmetric’, (反射延拓)‘reflect’, (缠绕延拓)‘wrap’。
cval:如果延拓方式设为常值,则该参数对应该常数值,可选项。
anti_aliasing:bool型,可选项,控制是否进行抗混叠处理。
anti_aliasing_sigma:实型或实型元组,可选项,用于控制进行抗混叠处理是所用高通滤波器的标准差。
返回值:
scaled:调整后的图像:ndarray型,数据类型与输入图像一致。
尺度缩放实例:
from skimage import data
from skimage.transform import rescale
image = data.camera()
print(image.shape)
img1 = rescale(image, 0.5).shape
print(ima1.shape)
img2 = rescale(image, 2.0).shape
print(ima2.shape)
三行输出分别为:(512,512)、(256, 256)、(1024, 1024)。
4.2.2 改变尺寸(resize)
Skimage使用resize函数将图像放缩到特定的尺寸。
以下是resize函数的声明:
resize(image, output_shape, order, mode, cval, clip, preserve_range, anti_aliasing, anti_aliasing_sigma)
部分参数说明:
- image:输入图像:ndarray型,可以是单通道/3/4通道图像。
output_shape:输出图像的尺寸,实型(或实型元组)单独设置的放缩之后的数值。
返回值:
resized:调整尺寸后的图像:ndarray型,数据类型与输入图像一致。
尺度缩放实例:
from skimage import data
from skimage.transform import resize
image = data.camera()
img_resize = resize(image, (150, 250)).shape
print(img_resize.shape)
输出为:(150 250)。
rescale和resize可以完成类似的功能。两者比较,如果是进行整数倍的放大/缩小,则用rescale函数,速度更快;否则,用resize更方便。
抗混叠效应
rescale和resize两个函数的参数中,都预设了anti_aliasing参数作为是否进行抗混叠操作的标识。如果设置为True,则首先对原图像进行高斯平滑处理,并用参数anti_aliasing_sigma设定所用高斯平滑滤波器的方差大小。
混叠效应是一种图像下采样处理过程中出现的干扰情况,在此简要介绍。
下图由多条黑白条间隔构成(如左图所示),在下采样处理时,一些黑色和白色的弧线将太细,无法表示正常显示为弧线,如右侧小图所示。
(混叠干扰图示,左图为原图,右图为下采样图像,图像来自 Pixel Mixing (entropymine.com))
图像混叠现象出现的根本原因在于,下采样的采样频率低于采样区域最高频率的两倍,导致信息丢失。有两种思路用于消除混叠现象。一是直接提高采样频率,即减小下采样间隔,但该方法效果有限;第二种是在采样频率固定的情况下,可通过低通滤波器(如高斯低通)抑制原图像的高频信息,降低最高频率,从而达到消除混叠现象的目的。因此,rescale和resize两函数提供的抗混叠效应可以简单认为是“先平滑后下采样”的过程。
4.2.3 基于局部均值的下采样(downscale_local_mean)
Skimage使用downscale_local_mean函数完成一种抗混叠下采样。
以下是downscale_local_mean函数的声明:
downscale_local_mean(image, factors, cval=0, clip=True)
部分参数说明:
- image:输入图像:ndarray型,可以是单通道/3/4通道图像。
factor:放缩因子,整型数组,用于设置每个轴的整数倍下采样因子,或者可简单认为是进行下采样时采样点对应于原图的子块大小。
cval:下采样时用于填充的常数值,默认为0。
clip:当前版本无效。
返回值:
image:下采样处理后的图像,float64型。
下采样图像中的每一个点对应于原图中的一个子块,子块的大小由参数factor确定,该函数计算每一个子块内各像素点强度值的平均值,并用该均值作为下采样图像对应像素点的强度值。其实整个过程等价于先对原图像求邻域均值,然后下采样的过程,只不过这样处理的计算量会较大。
以下给出的是来自官网的代码示例。
import numpy as np
from skimage.transform import downscale_local_mean
a = np.arange(15).reshape(3, 5)
print(a)
result = downscale_local_mean(a, (2, 3))
print(result)
输出结果为:
array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]])
array([[3.5, 4. ], [5.5, 4.5]])
以第一个采样值3.5计算过程为例,子窗口大小为2*3,即“两行三列”,从原图中取出的子块为[0,1,2;5,6,7],强度值总和为21,均值为21/6=3.5。然后用3.5作为下采样处理后(0,0)位置像素点的灰度值。
4.2.4 基于局部均值的尺寸调整(resize_local_mean)
Skimage库使用resize_local_mean函数官完成一种基于局部均值的下采样/基于双线性插值的上采样技术
该函数功能强大,集成了上述三个函数的主要功能。以下是该下函数的声明:
resize_local_mean(image, output_shape, grid_mode, preserve_range, channel_axis)
部分参数说明:
- image:输入图像:ndarray型,可以是单通道/3/4通道图像。
output_shape:输出图像大小。
grid_mode:插值图像像素位置确定方式。
preserve_range:是否保持原来的取值范围。
channel_axis:需要处理的通道序号。
返回值:
resized:调整后的图像。
该函数实现了一种称为“像素混合”插值方法,其工作原理参考参考文献【1】。
4.2.5 综合实例
本节给出一个图像放缩变换的综合实例。该实例在官网的相关实例基础上略加改动得到。
首先加载必要的扩展库/模块,并设置显示环境。(本实例再次列出,后面的实例默认忽略)
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
import numpy as np
from matplotlib import pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei' #显示图形中的文字类型为黑体
接下来读取图像,并使用本节介绍的各种缩放函数,完成缩放操作。
from skimage import io,color,data
from skimage.transform import rescale, resize, downscale_local_mean
image = color.rgb2gray(data.astronaut())
image_rescaled = rescale(image, 0.25, anti_aliasing=False)
image_resized = resize(image, (image.shape[0] // 4, image.shape[1] // 4),
anti_aliasing=True)
image_downscaled = downscale_local_mean(image, (8, 8))
fig, axes = plt.subplots(nrows=2, ncols=2)
ax = axes.ravel()
ax[0].imshow(image, cmap='gray')
ax[0].set_title("Original image")
ax[1].imshow(image_rescaled, cmap='gray')
ax[1].set_title("Rescaled image (no aliasing)")
ax[2].imshow(image_resized, cmap='gray')
ax[2].set_title("Resized image (aliasing)")
ax[3].imshow(image_downscaled, cmap='gray')
ax[3].set_title("Downscaled image (aliasing)")
ax[0].set_xlim(0, 512)
ax[0].set_ylim(512, 0)
plt.tight_layout()
plt.show()
下面是处理结果:
![](https://i-blog.csdnimg.cn/blog_migrate/5e443020864ec4e52f2ba14325a2b7e8.png)
参考文献:
【1】“pixel mixing”插值算法:https://entropymine.com/imageworsener/pixelmixing/
(本节初稿完成时间:2024-02-04;修订稿完成时间:2024-07-24)
(欢迎对DIP+python算法开发感兴趣的初学者,尤其是相关专业本科和低年级研究生关注,本专栏完将持续更新,敬请关注)