OpenCV Python gira la imagen en X grados alrededor de un punto específico

Me resulta difícil encontrar ejemplos para rotar una imagen alrededor de un punto específico por un ángulo específico (a menudo muy pequeño) en Python utilizando OpenCV.

Esto es lo que tengo hasta ahora, pero produce una imagen resultante muy extraña, pero se gira un poco:

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 

 import numpy as np def rotateImage(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 

Suponiendo que está utilizando la versión cv2, ese código encuentra el centro de la imagen que desea rotar, calcula la matriz de transformación y se aplica a la imagen.

O mucho más fácil usar SciPy

 from scipy import ndimage #rotation angle in degree rotated = ndimage.rotate(image_to_rotate, 45) 

Vea aquí para más información de uso.

La función cv2.warpAffine toma el parámetro de forma en orden inverso: (columna, fila) que las respuestas anteriores no mencionan. Esto es lo que funcionó para mí:

 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 
 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 
 import imutils vs = VideoStream(src=0).start() ... while (1): frame = vs.read() ... frame = imutils.rotate(frame, 45) 

Más: https://github.com/jrosebr1/imutils

El ajuste rápido a @ alex-rodrigues responde … se ocupa de la forma, incluido el número de canales.

 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) 

Tuve problemas con algunas de las soluciones anteriores, con obtener el “bounding_box” correcto o el nuevo tamaño de la imagen. Por lo tanto aquí está mi versión.

 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