使用 scikit-image warp 实现漩涡变换

334 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第13天,点击查看活动详情

前言

使用 scikit-image warp 函数执行图像变换一节中,我们学习了如何执行图像的线性变换,在本节中,我们将学习如何实现图像的非线性变换——漩涡变换 (swirl transform)。

使用 scikit-image warp 实现漩涡变换

使用 scikit-image warp 函数执行图像变换一节,我们已经学习了如何使用 scikit-image 库中的 warp() 函数执行线性变换。在本节中,我们将学习如何将 warp() 函数用于实现称为漩涡变换的非线性变换。我们假设输出图像中的坐标为 (x,y)(x,y),漩涡变换的反向映射首先应计算其相对于中心 (x0,y0) 的极性坐标:

θ=arctan(yx)ρ=(xx0)2+(yy0)2\theta=arctan(\frac y x) \\ ρ=\sqrt {(x-x_0)^2+(y-y_0)^2}

然后,根据以下公式对其进行变换:

r=ln2radious5θ=ψ+seρr+θr=ln2\cdot \frac {radious} 5 \\ \theta'=ψ+s\cdot e^{-\frac ρ r+\theta}

其中 ψψ 表示旋转角度,ss 表示像素值强度。接下来,我们利用 warp() 函数实现漩涡变换。

(1) 首先,导入所需库,并定义 swirl() 函数,该函数根据上述数学公式实现像素漩涡变换:

from skimage.io import imread
from skimage.transform import warp
import matplotlib.pylab as plt
import numpy as np

def swirl(xy, x0, y0, R):
    r = np.sqrt((xy[:,1]-x0)**2 + (xy[:,0]-y0)**2)
    a = np.pi*r / R
    xy[:, 1] = (xy[:, 1]-x0)*np.cos(a) + (xy[:, 0]-y0)*np.sin(a) + x0
    xy[:, 0] = -(xy[:, 1]-x0)*np.sin(a) + (xy[:, 0]-y0)*np.cos(a) + y0
    return xy

(2) 读取输入图像,然后将图像与 swirl() 函数输入参数调用 warp() 函数,以将非线性变换应用于输入图像:

im = imread('1.png')
print(im.shape)
im1 = warp(im, swirl, map_args={'x0':250, 'y0':350, 'R':600})
plt.figure(figsize=(20,10))
plt.subplot(121), plt.imshow(im), plt.axis('off'), plt.title('Input image', size=10)
plt.subplot(122), plt.imshow(im1), plt.axis('off'), plt.title('Output image', size=10)
plt.show()

函数 swirl() 接受参数 xyx0y0r,并根据 warp() 函数的 map_args 参数进行设定。

执行以上代码,可以得到以下结果图像:

Figure_5.png

需要注意的是,x0y0R 参数传递给 swirl() 函数,通过修改这些参数值,可以观察到不同参数对输出图像的影响。