OpenCV Python围绕特定点旋转图像X度

时间:2012-01-27 23:59:01

标签: python opencv rotation

我很难找到使用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

11 个答案:

答案 0 :(得分:41)

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

假设您正在使用cv2版本,该代码会找到您要旋转的图像的中心,计算变换矩阵并应用于图像。

答案 1 :(得分:26)

或者更容易使用 SciPy

from scipy import ndimage

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

here 了解更多使用信息。

答案 2 :(得分:8)

cv2.warpAffine函数以相反的顺序获取shape参数:( 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

答案 3 :(得分:7)

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 :(得分:4)

import imutils

vs = VideoStream(src=0).start()
...

while (1):
   frame = vs.read()
   ...

   frame = imutils.rotate(frame, 45)

更多:https://github.com/jrosebr1/imutils

答案 5 :(得分:3)

快速调整@ 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)

答案 6 :(得分:3)

我遇到了上述某些解决方案的问题,无法获得正确的“ 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

答案 7 :(得分:1)

您可以使用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()功能来创建跟踪栏。然后,您可以轻松地将其旋转到所需的任何角度。有关实现的完整详细信息,也可以在此处找到-actually defer to the Compare option for your file or project

答案 8 :(得分:1)

您可以使用以下代码:

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")       

答案 9 :(得分:0)

您可以简单地使用imutils包进行轮换。它有两种方法

  1. 旋转:以指定角度旋转图像。但是缺点是如果图像不是正方形图像,可能会被裁剪掉。
  2. Rotate_bound :它克服了旋转发生的问题。旋转图像时,它会相应地调整图像的大小。

您可以在此博客上获得更多信息: https://www.pyimagesearch.com/2017/01/02/rotate-images-correctly-with-opencv-and-python/

答案 10 :(得分:0)

这是一个仅使用 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