通过仿射变换将图片旋转10度不使用opencv
以下是Python代码实现:
import numpy as np
from PIL import Image
# 读取图片
img = Image.open('image.jpg')
# 将图片转为灰度图
img = img.convert('L')
# 将图片转为numpy数组
img_array = np.array(img)
# 获取图片宽度和高度
width, height = img.size
# 将图片中心点设为旋转中心
center_x, center_y = width/2, height/2
# 将角度转为弧度
angle = np.deg2rad(10)
# 定义仿射变换矩阵
M = np.array([[np.cos(angle), -np.sin(angle), 0],
[np.sin(angle), np.cos(angle), 0],
[0, 0, 1]])
# 定义反向仿射变换矩阵
M_inv = np.linalg.inv(M)
# 定义输出图像的宽度和高度
out_width = int(np.ceil(width*np.abs(np.cos(angle))+height*np.abs(np.sin(angle))))
out_height = int(np.ceil(height*np.abs(np.cos(angle))+width*np.abs(np.sin(angle))))
# 创建输出图像的numpy数组
out_array = np.zeros((out_height, out_width), dtype=np.uint8)
# 遍历输出图像的每个像素,计算其在输入图像中对应的像素位置,并进行插值
for i in range(out_height):
for j in range(out_width):
# 计算输出图像中像素位置对应的输入图像中的位置
x, y, _ = np.dot(M_inv, np.array([j-center_x, i-center_y, 1]))
x, y = int(np.round(x+center_x)), int(np.round(y+center_y))
# 判断该位置是否在输入图像中
if x >= 0 and x < width and y >= 0 and y < height:
# 进行插值
out_array[i, j] = img_array[y, x]
# 将numpy数组转为PIL Image对象
out_img = Image.fromarray(out_array)
# 显示输出图像
out_img.show()
# 保存输出图像
out_img.save('output.jpg')
注意,上述代码中的插值方法为最近邻插值,即将输出图像中每个像素对应的输入图像中的位置四舍五入到最近的整数,并将该位置的像素值作为输出像素的值。如果需要更高质量的插值方法,可以使用双线性插值或双立方插值等方法。
原文地址: https://www.cveoy.top/t/topic/b1mR 著作权归作者所有。请勿转载和采集!