深入理解旋转变换的原理、实现与应用
旋转变换是图像几何变换的重要组成部分,用于绕指定中心点旋转图像一定角度。
旋转变换是指将图像绕某个固定点(通常是图像中心)按指定角度旋转的操作。设原始点为(x, y),旋转角度为theta,则变换后的点为(x', y'):
| 角度 | cosθ | sinθ | 效果 |
|---|---|---|---|
| 90° | 0 | 1 | 顺时针 90 度 |
| 180° | -1 | 0 | 旋转 180 度 |
| 45° | √2/2 | √2/2 | 旋转 45 度 |
x' = x cos(theta) - y sin(theta)
y' = x sin(theta) + y cos(theta)
在齐次坐标系下,绕原点的旋转变换可以用矩阵形式表示:
[x'] [cos(theta) -sin(theta) 0] [x]
[y'] = [sin(theta) cos(theta) 0] [y]
[1 ] [ 0 0 1] [1]
若绕任意点(cx, cy)旋转,则需要先平移到原点,再旋转,最后平移回去。
import cv2
import numpy as np
import matplotlib.pyplot as plt
def rotation_transform(image_path, angle, scale=1.0):
"""
实现图像旋转变换
:param image_path: 输入图像路径
:param angle: 旋转角度(度),正值为逆时针旋转
:param scale: 缩放因子,默认为1.0
:return: 原图和旋转后的图像
"""
# 读取图像
img = cv2.imread(image_path)
height, width = img.shape[:2]
# 计算旋转中心点
center = (width // 2, height // 2)
# 计算旋转矩阵
rotation_matrix = cv2.getRotationMatrix2D(center, angle, scale)
# 应用旋转变换
rotated = cv2.warpAffine(img, rotation_matrix, (width, height))
return img, rotated
def manual_rotation(image_path, angle):
"""
手动实现图像旋转变换
:param image_path: 输入图像路径
:param angle: 旋转角度(度)
:return: 旋转后的图像
"""
import math
# 读取图像
img = cv2.imread(image_path)
height, width = img.shape[:2]
# 将角度转换为弧度
rad = math.radians(angle)
cos_val = math.cos(rad)
sin_val = math.sin(rad)
# 计算旋转中心
center_x, center_y = width / 2, height / 2
# 创建输出图像
rotated = np.zeros_like(img)
# 对输出图像的每个像素进行反向映射
for i in range(height):
for j in range(width):
# 将坐标系中心移到图像中心
x = j - center_x
y = i - center_y
# 应用反向旋转矩阵
orig_x = int(cos_val * x + sin_val * y + center_x)
orig_y = int(-sin_val * x + cos_val * y + center_y)
# 检查原始坐标是否在图像范围内
if 0 <= orig_x < width and 0 <= orig_y < height:
rotated[i, j] = img[orig_y, orig_x]
return img, rotated
def rotation_with_interpolation(image_path, angle, scale=1.0):
"""
带插值的旋转变换
:param image_path: 输入图像路径
:param angle: 旋转角度(度)
:param scale: 缩放因子
:return: 原图和旋转后的图像
"""
# 读取图像
img = cv2.imread(image_path)
height, width = img.shape[:2]
# 计算旋转中心点
center = (width // 2, height // 2)
# 计算旋转矩阵
rotation_matrix = cv2.getRotationMatrix2D(center, angle, scale)
# 应用旋转变换,使用双线性插值
rotated = cv2.warpAffine(img, rotation_matrix, (width, height),
flags=cv2.INTER_LINEAR,
borderMode=cv2.BORDER_REFLECT)
return img, rotated
# 使用示例
if __name__ == "__main__":
# 注意:需要提供实际的图像路径
# img, result = rotation_transform('image.jpg', 45)
# manual_img, manual_result = manual_rotation('image.jpg', 45)
# interp_img, interp_result = rotation_with_interpolation('image.jpg', 45)
pass