跳至主要內容

Image processing(平移)

LPrincess大约 3 分钟image

上课方法: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()

效果图:

上次编辑于:
贡献者: L-mj0