图像仿射变换之图像平移 python实现

请参考：图解图像仿射变换：https://www.cnblogs.com/wojianxin/p/12518393.html

 1 import cv2
2 import numpy as np
3
4 # 图像仿射变换->图像平移
5 def affine(img, a, b, c, d, tx, ty):
6     H, W, C = img.shape
7
8     # temporary image
9     tem = img.copy()
10     img = np.zeros((H+2, W+2, C), dtype=np.float32)
11     img[1:H+1, 1:W+1] = tem
12
13     # get new image shape
14     H_new = np.round(H * d).astype(np.int)
15     W_new = np.round(W * a).astype(np.int)
16     out = np.zeros((H_new+1, W_new+1, C), dtype=np.float32)
17
18     # get position of new image
19     x_new = np.tile(np.arange(W_new), (H_new, 1))
20     y_new = np.arange(H_new).repeat(W_new).reshape(H_new, -1)
21
22     # get position of original image by affine
23     adbc = a * d - b * c
24     x = np.round((d * x_new  - b * y_new) / adbc).astype(np.int) - tx + 1
25     y = np.round((-c * x_new + a * y_new) / adbc).astype(np.int) - ty + 1
26
27     # 避免目标图像对应的原图像中的坐标溢出
28     x = np.minimum(np.maximum(x, 0), W+1).astype(np.int)
29     y = np.minimum(np.maximum(y, 0), H+1).astype(np.int)
30
31     # assgin pixcel to new image
32     out[y_new, x_new] = img[y, x]
33
34     out = out[:H_new, :W_new]
35     out = out.astype(np.uint8)
36
37     return out
38
39
42
43 # Affine : 平移，tx(W向)：向右30；ty(H向)：向上100
44 out = affine(image1, a=1, b=0, c=0, d=1, tx=30, ty=-100)
45
46 # Save result
47 cv2.imshow("result", out)
48 cv2.imwrite("out.jpg", out)
49 cv2.waitKey(0)
50 cv2.destroyAllWindows()

① 原图像进行仿射变换时，原图像中的坐标可能超出了目标图像的边界，需要对原图像坐标进行截断处理。如何做呢？首先，计算目标图像坐标对应的原图像坐标，算法如下：

以下代码实现了该逆变换：

# get position of original image by affine

adbc = a * d - b * c

x = np.round((d * x_new  - b * y_new) / adbc).astype(np.int) - tx + 1

y = np.round((-c * x_new + a * y_new) / adbc).astype(np.int) - ty + 1

然后对原图像坐标中溢出的坐标进行截断处理（取边界值），下面代码提供了这个功能：

x = np.minimum(np.maximum(x, 0), W+1).astype(np.int)

y = np.minimum(np.maximum(y, 0), H+1).astype(np.int)

原图像范围：长W，高H

② 难点解答：

x_new = np.tile(np.arange(W_new), (H_new, 1))

y_new = np.arange(H_new).repeat(W_new).reshape(H_new, -1)

x_new 矩阵横向长 W_new，纵向长H_new ↑

y_new 矩阵横向长 W_new，纵向长H_new ↑

造这两个矩阵是为了这一步：

# assgin pixcel to new image

out[y_new, x_new] = img[y, x]

未经作者允许，请勿随意转载抄袭，抄袭情节严重者，作者将考虑追究其法律责任，创作不易，感谢您的理解和配合！

posted on 2020-03-18 19:15  我坚信阳光灿烂  阅读(2060)  评论(0编辑  收藏  举报