2017-05-10 506 views
2

想象我有這些圖片:的OpenCV的Python:旋轉圖像不裁剪邊

ttps://i.stack.imgur.com/jjRfe.png

我想從左邊的圖像,如中間,不正確的的圖像進行旋轉。我如何使用Python和OpenCV來做到這一點。我看了getRotationMatrix2DwarpAffine,但關於它的例子將我的形象轉化爲正確的形象。

回答

2

因爲我不知道你的代碼,我仍然會猜測使用imutils.rotate_bound函數可以解決這個問題。例如:rotate = imutils.rotate_bound(image, angle)

+0

imutils是OpenCV的一部分還是應該添加它? –

+0

您將需要通過'pip install imutils'安裝它,並將其導入當然'import imutils'到您的python代碼 – korbi

+0

好的,謝謝,我會試試! –

0

這是迄今爲止我發現的用於旋轉圖像的最佳解決方案,同時避免裁剪圖像。

Rotate an image without cropping in OpenCV in C++

import cv2 

def rotate_image(mat, angle): 
    """ 
    Rotates an image (angle in degrees) and expands image to avoid cropping 
    """ 

    height, width = mat.shape 
    image_center = (width/2, height/2) # getRotationMatrix2D needs coordinates in reverse order (width, height) compared to shape 

    rotation_mat = cv2.getRotationMatrix2D(image_center, angle, 1.) 

    # rotation calculates the cos and sin, taking absolutes of those. 
    abs_cos = abs(rotation_mat[0,0]) 
    abs_sin = abs(rotation_mat[0,1]) 

    # find the new width and height bounds 
    bound_w = int(height * abs_sin + width * abs_cos) 
    bound_h = int(height * abs_cos + width * abs_sin) 

    # subtract old image center (bringing image back to origo) and adding the new image center coordinates 
    rotation_mat[0, 2] += bound_w/2 - image_center[0] 
    rotation_mat[1, 2] += bound_h/2 - image_center[1] 

    # rotate image with the new bounds and translated rotation matrix 
    rotated_mat = cv2.warpAffine(mat, rotation_mat, (bound_w, bound_h)) 
    return rotated_mat 

您可以添加檢查,以避免一些計算時的角度是90 * N,但該功能適用​​於任何角度上班的。

0

您也可以使用填充,即將邊框添加到圖像的邊緣,然後旋轉它以避免從原始圖像裁剪。

def rotate_im(image, angle) 
    image_height = image.shape[0] 
    image_width = image.shape[1] 
    diagonal_square = (image_width*image_width) + (
     image_height* image_height 
    ) 
    # 
    diagonal = round(sqrt(diagonal_square)) 
    padding_top = round((diagonal-image_height)/2) 
    padding_bottom = round((diagonal-image_height)/2) 
    padding_right = round((diagonal-image_width)/2) 
    padding_left = round((diagonal-image_width)/2) 
    padded_image = cv2.copyMakeBorder(image, 
             top=padding_top, 
             bottom=padding_bottom, 
             left=padding_left, 
             right=padding_right, 
             borderType=cv2.BORDER_CONSTANT, 
             value=0 
      ) 
    padded_height = padded_image.shape[0] 
    padded_width = padded_image.shape[1] 
    transform_matrix = cv2.getRotationMatrix2D(
       (padded_height/2, 
       padded_width/2), # center 
       angle, # angle 
     1.0) # scale 
    rotated_image = cv2.warpAffine(padded_image, 
            transform_matrix, 
            (diagonal, diagonal), 
            flags=cv2.INTER_LANCZOS4) 
    return rotated_image