OpenCV Python 围绕特定点将图像旋转 X 度
- 2025-03-13 09:12:00
- admin 原创
- 72
问题描述:
我很难找到使用 OpenCV 在 Python 中将图像围绕特定点以特定(通常非常小)的角度旋转的示例。
这是我目前所得到的,但它产生了一个非常奇怪的结果图像,但它有所旋转:
def rotateImage( image, angle ):
if image != None:
dst_image = cv.CloneImage( image )
rotate_around = (0,0)
transl = cv.CreateMat(2, 3, cv.CV_32FC1 )
matrix = cv.GetRotationMatrix2D( rotate_around, angle, 1.0, transl )
cv.GetQuadrangleSubPix( image, dst_image, transl )
cv.GetRectSubPix( dst_image, image, rotate_around )
return dst_image
解决方案 1:
import numpy as np
import cv2
def rotate_image(image, angle):
image_center = tuple(np.array(image.shape[1::-1]) / 2)
rot_mat = cv2.getRotationMatrix2D(image_center, angle, 1.0)
result = cv2.warpAffine(image, rot_mat, image.shape[1::-1], flags=cv2.INTER_LINEAR)
return result
假设您使用的是 cv2 版本,该代码会找到您想要旋转的图像的中心,计算变换矩阵并应用于图像。
解决方案 2:
或者更容易使用
SciPy
from scipy import ndimage
#rotation angle in degree
rotated = ndimage.rotate(image_to_rotate, 45)
请参阅
此处
了解更多使用信息。
解决方案 3:
def rotate(image, angle, center = None, scale = 1.0):
(h, w) = image.shape[:2]
if center is None:
center = (w / 2, h / 2)
# Perform the rotation
M = cv2.getRotationMatrix2D(center, angle, scale)
rotated = cv2.warpAffine(image, M, (w, h))
return rotated
解决方案 4:
我对上述某些解决方案存在问题,无法获得正确的“bounding_box”或图像的新大小。因此,这是我的版本
def rotation(image, angleInDegrees):
h, w = image.shape[:2]
img_c = (w / 2, h / 2)
rot = cv2.getRotationMatrix2D(img_c, angleInDegrees, 1)
rad = math.radians(angleInDegrees)
sin = math.sin(rad)
cos = math.cos(rad)
b_w = int((h * abs(sin)) + (w * abs(cos)))
b_h = int((h * abs(cos)) + (w * abs(sin)))
rot[0, 2] += ((b_w / 2) - img_c[0])
rot[1, 2] += ((b_h / 2) - img_c[1])
outImg = cv2.warpAffine(image, rot, (b_w, b_h), flags=cv2.INTER_LINEAR)
return outImg
解决方案 5:
cv2.warpAffine 函数以相反的顺序采用形状参数:(col,row),上面的答案没有提到。以下是对我有用的方法:
import numpy as np
def rotateImage(image, angle):
row,col = image.shape
center=tuple(np.array([row,col])/2)
rot_mat = cv2.getRotationMatrix2D(center,angle,1.0)
new_image = cv2.warpAffine(image, rot_mat, (col,row))
return new_image
解决方案 6:
您可以简单地使用该imutils
包进行旋转。它有两种方法
旋转:以指定的角度旋转图像。然而缺点是如果它不是方形图像,图像可能会被裁剪。
rotate_bound:它解决了旋转时出现的问题。它在旋转图像的同时相应地调整图像的大小。
您可以在此博客上获取更多信息:
https://www.pyimagesearch.com/2017/01/02/rotate-images-correctly-with-opencv-and-python/
解决方案 7:
import imutils
vs = VideoStream(src=0).start()
...
while (1):
frame = vs.read()
...
frame = imutils.rotate(frame, 45)
更多详情: https: //github.com/jrosebr1/imutils
解决方案 8:
快速调整@alex-rodrigues 的答案...处理包括通道数量在内的形状。
import cv2
import numpy as np
def rotateImage(image, angle):
center=tuple(np.array(image.shape[0:2])/2)
rot_mat = cv2.getRotationMatrix2D(center,angle,1.0)
return cv2.warpAffine(image, rot_mat, image.shape[0:2],flags=cv2.INTER_LINEAR)
解决方案 9:
您需要一个大小为 2x3 的同质矩阵。第一个 2x2 是旋转矩阵,最后一列是平移向量。
构建转换矩阵的方法如下:
# Exemple with img center point:
# angle = np.pi/6
# specific_point = np.array(img.shape[:2][::-1])/2
def rotate(img: np.ndarray, angle: float, specific_point: np.ndarray) -> np.ndarray:
warp_mat = np.zeros((2,3))
cos, sin = np.cos(angle), np.sin(angle)
warp_mat[:2,:2] = [[cos, -sin],[sin, cos]]
warp_mat[:2,2] = specific_point - np.matmul(warp_mat[:2,:2], specific_point)
return cv2.warpAffine(img, warp_mat, img.shape[:2][::-1])
解决方案 10:
您可以使用 opencv python 轻松旋转图像-
def funcRotate(degree=0):
degree = cv2.getTrackbarPos('degree','Frame')
rotation_matrix = cv2.getRotationMatrix2D((width / 2, height / 2), degree, 1)
rotated_image = cv2.warpAffine(original, rotation_matrix, (width, height))
cv2.imshow('Rotate', rotated_image)
如果您正在考虑创建轨迹栏,那么只需使用创建轨迹栏cv2.createTrackbar()
并从主脚本中调用该函数funcRotate()
即可。然后,您可以轻松地将其旋转到您想要的任何角度。有关实现的完整详细信息也可以在此处找到 -使用 opencv 中的轨迹栏以任意角度旋转图像
解决方案 11:
下面是仅使用 openCV 绕任意点 (x,y) 旋转的示例
def rotate_about_point(x, y, degree, image):
rot_mtx = cv.getRotationMatrix2D((x, y), angle, 1)
abs_cos = abs(rot_mtx[0, 0])
abs_sin = abs(rot_mtx[0, 1])
rot_wdt = int(frm_hgt * abs_sin + frm_wdt * abs_cos)
rot_hgt = int(frm_hgt * abs_cos + frm_wdt * abs_sin)
rot_mtx += np.asarray([[0, 0, -lftmost_x],
[0, 0, -topmost_y]])
rot_img = cv.warpAffine(image, rot_mtx, (rot_wdt, rot_hgt),
borderMode=cv.BORDER_CONSTANT)
return rot_img
解决方案 12:
您可以使用以下代码:
import numpy as np
from PIL import Image
import math
def shear(angle,x,y):
tangent=math.tan(angle/2)
new_x=round(x-y*tangent)
new_y=y
#shear 2
new_y=round(new_x*math.sin(angle)+new_y)
#since there is no change in new_x according to the shear matrix
#shear 3
new_x=round(new_x-new_y*tangent)
#since there is no change in new_y according to the shear matrix
return new_y,new_x
image = np.array(Image.open("test.png"))
# Load the image
angle=-int(input("Enter the angle :- "))
# Ask the user to enter the angle of rotation
# Define the most occuring variables
angle=math.radians(angle)
#converting degrees to radians
cosine=math.cos(angle)
sine=math.sin(angle)
height=image.shape[0]
#define the height of the image
width=image.shape[1]
#define the width of the image
# Define the height and width of the new image that is to be formed
new_height = round(abs(image.shape[0]*cosine)+abs(image.shape[1]*sine))+1
new_width = round(abs(image.shape[1]*cosine)+abs(image.shape[0]*sine))+1
output=np.zeros((new_height,new_width,image.shape[2]))
image_copy=output.copy()
# Find the centre of the image about which we have to rotate the image
original_centre_height = round(((image.shape[0]+1)/2)-1)
#with respect to the original image
original_centre_width = round(((image.shape[1]+1)/2)-1)
#with respect to the original image
# Find the centre of the new image that will be obtained
new_centre_height= round(((new_height+1)/2)-1)
#with respect to the new image
new_centre_width= round(((new_width+1)/2)-1)
#with respect to the new image
for i in range(height):
for j in range(width):
#co-ordinates of pixel with respect to the centre of original image
y=image.shape[0]-1-i-original_centre_height
x=image.shape[1]-1-j-original_centre_width
#Applying shear Transformation
new_y,new_x=shear(angle,x,y)
new_y=new_centre_height-new_y
new_x=new_centre_width-new_x
output[new_y,new_x,:]=image[i,j,:]
pil_img=Image.fromarray((output).astype(np.uint8))
pil_img.save("rotated_image.png")
扫码咨询,免费领取项目管理大礼包!