Python图像处理-----几何变换

一、图像几何变换理论

图像几何变换不改变图像的像素值,在图像平面上进行像素变换。适当的几
何变换可以最大程度地消除由于成像角度、透视关系乃至镜头自身原因所造成的
几何失真所产生的负面影响。几何变换常常作为图像处理应用的预处理步骤,是
图像归一化的核心工作之一[1]。
一个几何变换需要两部分运算:

  • 空间变换:包括平移、缩放、旋转和正平行投影等,需要用它来表示输
    出图像与输入图像之间的像素映射关系。
  • 灰度插值算法:按照这种变换关系进行计算,输出图像的像素可能被映
    射到输入图像的非整数坐标上[2]。

图像几何变换在变换过程中会建立一种原图像像素与变换后图像像素之间的映射关系,通过这种关系,能够从一方的像素计算出另一方的像素的坐标位置。通常将图像坐标映射到输出的过程称作向前映射,反之,将输出图像映射到输入的过程称作向后映射。向后映射在实践中使用较多,原因是能够避免使用向前映射中出现映射不完全和映射重叠的问题。

对于数字图像而言,像素的坐标是离散型非负整数,但是在进行变换的过程
中有可能产生浮点坐标值。这在图像处理中是一个无效的坐标。为了解决这个问
题需要用到插值算法。常见算法如下:

  • 最近邻插值
  • 双线性插值
  • 双立方插值

图像变换是建立在矩阵运算基础上,通过矩阵运算可以很快找到对应关系。绍常见的图像几何变换,包括图形平移、图像缩放、图像旋转、图像镜像、图像仿射、图像透视等。

二、图像平移

图像平移是将图像中的所有像素点按照给定的平移量进行水平或垂直方向上的移动。假设原始像素的位置坐标为(x0,y0),经过平移量(△x,△y)后,坐标变为(x1, y1),如图所示:
在这里插入图片描述
用数学式子表示为公式,△x 和△y 称为平移量:

x 1 = x 0 + Δ x \mathrm{x}_{1}=\mathrm{x}_{0}+\Delta \mathrm{x} x1=x0+Δx
y 1 = y 0 + Δ y \mathrm{y}_{1}=\mathrm{y}_{0}+\Delta \mathrm{y} y1=y0+Δy

2.1 使用数学公式的实现方式为:

def translate_img(img, move_y, move_x):
    h, w, c = img.shape
    translated_img = np.zeros((h, w, c), dtype=np.uint8)
    for i in range(h):
        for j in range(w):
            if i >= move_y and j >= move_x:
                translated_img[i, j] = img[i - move_y, j - move_x]
    return translated_img

2.2 使用矩阵实现的方式为

用矩阵表示如公式所示:

[ x 1 y 1 1 ] = [ x 0 y 0 1 ] [ 1 0 0 0 1 0 Δ x Δ y 1 ] \begin{bmatrix}{x_{1}}&{y_{1}}&1\end{bmatrix} = \begin{bmatrix}{x_{0}}&{y_{0}}&1\end{bmatrix} \begin{bmatrix}{1}&{0}&{0}\\{0}&{1}&{0}\\{\Delta \mathrm{x}}&{\Delta \mathrm{y}}&{1}\end{bmatrix} [x1y11]=[x0y01] 10Δx01Δy001
式子中,矩阵称为平移变换矩阵或因子,△x 和△y 称为平移量。

def translate_image(image, move_x, move_y):
    # 平移矩阵
    translation_matrix = np.array([[1, 0, 0], [0, 1, 0], [move_x, move_y, 1]])
    height, width = image.shape[:2]
    translated_image = np.zeros([height, width, 3], dtype=np.uint8)
    for y in range(height):
        for x in range(width):
            translated_x, translated_y, _ = np.dot([x, y, 1], translation_matrix)
            if 0 <= translated_x < width and 0 <= translated_y < height:
                translated_image[translated_y, translated_x] = image[y, x]
    return translated_image

2.3 使用opencv

图像平移首先定义平移矩阵 M,再调用 warpAffine()函数实现平移,核心函数如下:
M = np.float32([[1, 0, x], [0, 1, y]])
M 表示平移矩阵,其中 x 表示水平平移量,y 表示垂直平移量

shifted = cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[,
borderValue]]]])

  • src 表示原始图像
  • M 表示平移矩阵
  • dsize 表示变换后的输出图像的尺寸大小
  • dst 为输出图像,其大小为 dsize,类型与 src 相同
  • flag 表示插值方法的组合和可选值
  • borderValue 表示像素外推法,当 borderMode =BORDER_TRANSPARENT 时,表示目标图像中的像素不会修改源图像中的“异常值”。
  • borderValue 用于边界不变的情况,默认情况下为 0
img = cv.imread("lena.webp")
h, w, c = img.shape
translated_img = translate_image(img, h // 3, w // 3)
img_all = np.hstack((img, translated_img))
cv.imshow("img", img_all)


M = np.float32([[1, 0, 100], [0, 1, 50]])
#获取原始图像列数和行数
rows, cols = img.shape[:2]
#图像平移
result = cv.warpAffine(img, M, (cols, rows))
#显示图像
cv.imshow("original", img)
cv.imshow("result", result)
#等待显示
cv.waitKey(0)
cv.destroyAllWindows()

三、图像缩放

图像缩放(image scaling)是指对数字图像的大小进行调整的过程。

3.1 用数学式子表示为公式(a为缩放系数):

x 1 = a ∗ x 0 \mathrm{x}_{1}=a*\mathrm{x}_{0} x1=ax0
y 1 = a ∗ y 0 \mathrm{y}_{1}=a*\mathrm{y}_{0} y1=ay0

def resize_img(img, x_size, y_size):
    h, w, c = img.shape
    translated_img = np.zeros((int(x_size*h), int(y_size*w), c), dtype=np.uint8)
    for i in range(h):
        for j in range(w):
                translated_img[int(i*x_size), int(j*y_size)] = img[i, j]
    return translated_img

3.2 用矩阵表示如公式所示:

[ x 1 y 1 1 ]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

优雅的心情

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值