机器视觉学习-day06-图像旋转
图像旋转指的是图像以某一点为中心,将图像中所有的像素点围绕该点旋转一定的角度,并且旋转后像素点组成的图案与原图案相同。
1 仿射变换
旋转、镜像、缩放、平移、剪切、不均匀缩放
仿射变换是一种二维坐标到二维坐标的线性变换,也就是只涉及一个平面内的二维图形,图像旋转是仿射变换的一种,它保持了二维图形变换的性质:
平直性:直线在经过变换后还是直线。
平行性:平行线在经过变换后还是平行线。
在图片旋转过程中可能会出现下面的问题:
1. 取整丢失精度
由于三角函数的值是小数,其乘积也是小数,但是OpenCV在计算的过程中会进行取整操作,因为像素点旋转之后的取整结果可能有重合,会导致转换后的图像丢失一部分像素信息。
2. 缩放丢失精度
例如原图的分辨率是10*10,放大之后变为20*20,图像由100个像素点变为400个像素点,那么多余的300个像素点数据如何而来?
再如原图的分辨率是20*20,缩小之后变为10*10,需要丢弃300个像素点,如何丢弃才能保证图像的正常显示?
使用插值法来解决上述出现的问题,插值是一种通过已知的数据点之前的关系推断或估计来获取新的数据点的方法,常用于仿射变换相关操作,包括但不限于图像放大、缩小、旋转变形等。
2 插值
2.1 最近邻插值(INTER_NEAREST):
速度最快,但是可能会导致图像出现锯齿状边缘(马赛克)和失真。
2.2 双线性插值(INTER_LINEAR):
相比于最近邻插值计算速度稍慢,但是效果大幅提升,适用于绝大多数场景。
2.3 像素区域插值(INTER_AREA):
更适合缩小图像且保持质量时使用。
2.4 双三次插值(INTER_CUBIC):
速度很慢,但是效果很好。
2.5 Lanczos(兰克索斯)插值(INTER_LANCZOS4):
速度最慢,效果最好。
3 边缘填充
图像旋转后,原来的四个角无对应的像素值,因此会使用(0,0,0)黑色填充,可以进行其他方法进行填充
3.1 边界复制 BORDER_REPLICATE
边界复制会将边界处的像素值进行复制,然后作为边界填充的像素值。
3.2 边界反射 BORDER_REFLECT
3.3 边界反射101 BORDER_REFLECT_101
3.4 边界常数 BORDER_CONSTANT
边界常数表示补充一个自定义的像素值,如黑色(0,0,0)
3.5 边界包裹 BORDER_WRAP
代码运行步骤:图片输入→单点旋转→图片变换→插值方法→边缘填充方法→图片输出
图片名24.jpg
import cv2
import numpy as npif __name__ == '__main__':# 1. 图片输入path = '24.jpg' # 定义图像文件路径image_np = cv2.imread(path) # 使用OpenCV读取图像文件,将图像数据存储为NumPy数组# 2. 单点旋转 + 图片旋转,相当于直接构建复合矩阵# (单点旋转和图片选择分不开)angle = 45 # 旋转角 :设置旋转角度为45度scale = 1 # 缩放比例:放大2倍# 获得二维旋转的仿射变换矩阵/创建旋转和缩放的变换矩阵M = cv2.getRotationMatrix2D((0, 0), # 旋转点:参数(0, 0)表示旋转中心点为图像左上角(原点)angle, # 旋转角度:参数angle指定旋转角度scale # 缩放比例:参数scale指定缩放比例)print(M) # 打印出变换矩阵的内容,便于调试和查看# 4.图片矫正. 插值方法 + 5. 边缘填充# 仿射变换:应用仿射变换到图像上rotation_image = cv2.warpAffine(image_np, # 输入的原始图像M, # 之前计算的变换矩阵(image_np.shape[1] * 2, image_np.shape[0] * 2), # 目标图像的分辨率flags=cv2.INTER_LANCZOS4, # 插值方法borderMode=cv2.BORDER_WRAP # 边界填充(边界包裹))"""(image_np.shape[1] * 2, image_np.shape[0] * 2)设置输出图像尺寸为原图的两倍flags=cv2.INTER_LANCZOS4指定使用Lanczos插值算法,提供高质量的图像重采样borderMode=cv2.BORDER_WRAP指定边界填充模式为环绕模式(边缘像素环绕到对侧)"""# 6. 图片输出cv2.imshow('rotation_image', rotation_image)cv2.imwrite('rotation_image.png', rotation_image)cv2.waitKey(0)
运行结果: