Image processing(平移)
大约 3 分钟
上课方法:OpenCV: cv2.warpAffine()
函数实现图像的平移操作。使用仿射变换矩阵来指定平移量。
img1 = cv2.imread("lenna.bmp",-1)
h,w = img1.shape[:2]
# 水平50 垂直150
m = np.float32([[1,0,50],[0,1,150]])
# 不扩大画布平移
# out = cv2.warpAffine(img1,m,(w,h))
# 扩大画布平移
out = cv2.warpAffine(img1,m,(w+50,h+150))
cv2.imwrite("out.jpg",out)
补充方法: PIL/Pillow: Image.transform()
方法可以对图像进行平移操作。使用 Affine
变换来指定平移量。类似于cv2.warpAffine()
代码:
from PIL import Image
img = Image.open("11.jpg")
# 定义仿射变换矩阵
m = (1,0,50,0,1,30)
img_translated = img.transform(img.size,Image.AFFINE,m)
img_translated.save("translated_image.jpg")
效果图:
NumPy: 使用 NumPy 库可以直接对图像数据进行操作,通过切片操作来实现图像的平移。这种方法适用于简单的平移操作,但不支持插值,因此可能会丢失部分图像信息。
代码:
from PIL import Image
import numpy as np
img = np.array(Image.open("11.jpg"))
# 定义偏移量
dx = 100
dy = 50
# 创建与原始图像相同大小的数组,用于存储平移后的图像
h,w,channels = img.shape
img_translated = np.zeros_like(img)
# 将原始图像的像素值复制到新数组中,并根据平移量进行调整
img_translated[max(0, dy):min(h, h+dy), max(0, dx):min(w, w+dx)] = img[max(0, -dy):min(h, h-dy), max(0, -dx):min(w, w-dx)]
# 将 NumPy 数组转换回图像对象
translated_image = Image.fromarray(img_translated)
translated_image.save("translated_image.jpg")
效果图:
skimage:skimage.transform.AffineTransform
,可以实现图像的平移操作 变换原理: 对图像的每个像素坐标进行重新采样(resampling) 对于平移变换,我们使用的是仿射变换(Affine Transformation)。仿射变换是一种重要的坐标变换,它包括了平移、旋转、缩放和错切等基本变换。仿射变换可以用一个3x3的变换矩阵来表示:
|a b tx|
|c d ty|
|0 0 1|
其中(tx, ty)表示平移的幅度,(a, b, c, d)分别表示缩放和旋转的系数。
在skimage中,AffineTransform
就是用来构建这个仿射变换矩阵的。我们只需要指定translation
参数,就可以构建出一个只含有平移分量的仿射变换矩阵。
接下来,warp
函数会遍历输出图像的每个像素坐标(x', y'),将其代入仿射变换矩阵的逆矩阵,得到对应的原始图像坐标(x, y):
|x'| |a b tx|^-1 |x|
|y'| = |c d ty| |y|
|1 | |0 0 1| |1|
然后,warp
函数会根据(x, y)的值,通过插值(interpolation)计算出原始图像在该点的像素值,并将这个值赋给输出图像的(x', y')像素。
代码:
import matplotlib.pyplot as plt
from skimage import io, transform
img = io.imread("11.jpg")
# 定义了一个仿射变换矩阵,表示沿x轴平移-50像素,沿y轴平移100像素
trans = transform.AffineTransform(translation=[-50,100])
# 使用这个变换矩阵对图像进行变换,`tf_shift.inverse`表示应用逆变换,`mode='wrap'`表示超出图像边界的像素值将被"环绕"。
img_translated = transform.warp(img, trans.inverse, mode='wrap')
# 显示原始图像和经过平移的图像
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 5))
ax = axes.ravel()
ax[0].imshow(img)
ax[0].set_title("Original")
ax[1].imshow(img_translated)
ax[1].set_title("Shifted")
plt.show()
效果图: