图像以原点 (0, 0) 为中心、顺时针旋转角度 θ 进行旋转的计算公式:
逆时针为负数,顺时针为正数
图像以任意点 (x0, y0) 为旋转中心、顺时针旋转角度 θ 的旋转操作,可以先将原点平移到旋转中心 (x0, y0) ,然后按照原点旋转,最后再平移回坐标原点的计算公式:
计算公式结果参考:cv2.getRotationMatrix2D的旋转矩阵的正确形式!!!
cv.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) → dst
参数 | 说明 |
---|---|
src | 表示输入图像。 |
M | 表示变换矩阵,2行3列。 |
dsize | 表示输出图像的大小,二元元组 (width, height)。 |
dst | 表示变换操作的输出图像,可选项。 |
flags | 表示插值方法,整型(int),可选项。 |
borderMode | 表示边界像素方法,整型(int),可选项,默认值为 cv.BORDER_REFLECT。 |
borderValue | 表示边界填充值,可选项,默认值为 0(黑色填充)。 |
值 | 说明 |
---|---|
cv.INTER_LINEAR | 表示双线性插值(默认方法)。 |
cv.INTER_AREA | 表示使用像素区域关系重采样,缩小图像时可以避免波纹出现。 |
cv.INTER_NEAREST | 表示最近邻插值。 |
cv.INTER_CUBIC | 表示 4x4 像素邻域的双三次插值。 |
cv.INTER_LANCZOS4 | 表示 8x8 像素邻域的Lanczos插值。 |
逆时针为负数,顺时针为正数
import cv2 as cv
import numpy as np
# 图像旋转(以原点(0,0)为中心旋转)
def image_rotate(src, rotate=0):
h,w,c = src.shape
cos_val = np.cos(np.deg2rad(rotate))
sin_val = np.sin(np.deg2rad(rotate))
M = np.float32([[cos_val, -sin_val, 0], [sin_val, cos_val, 0]])
img = cv.warpAffine(src, M, (w,h))
return img
if __name__ == "__main__":
img = cv.imread("./images/lena.jpg")
cv.imshow("origin", img)
cv.imshow("img_rotate_30", image_rotate(img,30))
cv.imshow("img_rotate_45", image_rotate(img,45))
cv.waitKey(0)
cv.destroyAllWindows()
import cv2 as cv
import numpy as np
# 图像旋转(以原点(0,0)为中心旋转)
def image_rotate(src, rotate=0):
h,w,c = src.shape
cos_val = np.cos(np.deg2rad(rotate))
sin_val = np.sin(np.deg2rad(rotate))
M = np.float32([[cos_val, sin_val, 0], [-sin_val, cos_val, 0]])
img = cv.warpAffine(src, M, (w,h))
return img
if __name__ == "__main__":
img = cv.imread("./images/lena.jpg")
cv.imshow("origin", img)
cv.imshow("img_rotate_30", image_rotate(img,30))
cv.imshow("img_rotate_45", image_rotate(img,45))
cv.waitKey(0)
cv.destroyAllWindows()
import cv2 as cv
import numpy as np
# 计算旋转变换矩阵
def handle_rotate_val(x,y,rotate):
cos_val = np.cos(np.deg2rad(rotate))
sin_val = np.sin(np.deg2rad(rotate))
return np.float32([
[cos_val, sin_val, x * (1 - cos_val) - y * sin_val],
[-sin_val, cos_val, x * sin_val + y * (1 - cos_val)]
])
# 图像旋转(以任意点为中心旋转)
def image_rotate(src, rotate=0):
h,w,c = src.shape
M = handle_rotate_val(w//2,h//2,rotate)
img = cv.warpAffine(src, M, (w,h))
return img
if __name__ == "__main__":
img = cv.imread("./images/lena.jpg")
cv.imshow("origin", img)
cv.imshow("img_rotate_30", image_rotate(img,30))
cv.imshow("img_rotate_45", image_rotate(img,45))
cv.waitKey(0)
cv.destroyAllWindows()
OpenCV 提供了 cv.getRotationMatrix2D 函数, 根据旋转角度和位移计算旋转变换矩阵 MAR。
cv.getRotationMatrix2D(center, angle, scale) → M
参数 | 说明 |
---|---|
center | 表示旋转中心坐标,二元元组 (x0, y0)。 |
angle | 表示旋转角度,单位为角度,逆时针为正数,顺时针为负数。 |
scale | 表示缩放因子。 |
import cv2 as cv
# 图像旋转(以任意点为中心旋转)
def image_rotate(src, rotate=0):
h,w,c = src.shape
M = cv.getRotationMatrix2D((w//2,h//2),rotate,1)
img = cv.warpAffine(src, M, (w,h))
return img
if __name__ == "__main__":
img = cv.imread("./images/lena.jpg")
cv.imshow("origin", img)
cv.imshow("img_rotate_30", image_rotate(img,30))
cv.imshow("img_rotate_45", image_rotate(img,45))
cv.waitKey(0)
cv.destroyAllWindows()
cv.rotate( src, rotateCode[, dst] ) → dst
参数 | 说明 |
---|---|
src | 表示变换操作的输入图像。 |
rotateCode | 表示枚举,指定旋转角度。 |
dst | 表示变换操作的输出图像,ndarray 多维数组。 |
值 | 说明 |
---|---|
cv.ROTATE_90_CLOCKWISE | 表示顺时针旋转 90 度。 |
cv.ROTATE_180 | 表示旋转 180 度。 |
cv.ROTATE_90_COUNTERCLOCKWISE | 表示逆时针旋转 90 度。 |
import cv2 as cv
import numpy as np
# 图像旋转(以特殊角度旋转)
def image_rotate(src):
img_90 = cv.rotate(src,cv.ROTATE_90_CLOCKWISE)
cv.imshow("ROTATE_90_CLOCKWISE", img_90)
img_180 = cv.rotate(src,cv.ROTATE_180)
cv.imshow("ROTATE_180", img_180)
img_270 = cv.rotate(src,cv.ROTATE_90_COUNTERCLOCKWISE)
cv.imshow("ROTATE_90_COUNTERCLOCKWISE", img_270)
return img
if __name__ == "__main__":
img = cv.imread("./images/lena.jpg")
cv.imshow("origin", img)
image_rotate(img)
cv.waitKey(0)
cv.destroyAllWindows()
np.rot90(src, k, axes) → dst
参数 | 说明 |
---|---|
src | 表示变换操作的输入图像。 |
k | 表示阵列旋转90度的次数。 |
axes | 表示 array 在轴定义的平面中旋转。 轴必须不同。 |
dst | 表示变换操作的输出图像。 |
import cv2 as cv
import numpy as np
# 图像旋转(以特殊角度旋转)
def image_rotate(src):
img_90 = np.rot90(src,1)
cv.imshow("rot90", img_90)
img_180 = np.rot90(src,2)
cv.imshow("rot180", img_180)
img_270 = np.rot90(src,3)
cv.imshow("rot270", img_270)
return img
if __name__ == "__main__":
img = cv.imread("./images/lena.jpg")
half_img = cv.resize(img,None,fx=0.5,fy=0.5)
cv.imshow("origin", half_img)
image_rotate(half_img)
cv.waitKey(0)
cv.destroyAllWindows()