2015-11-25 65 views
3

我在旋轉圖像後遇到了正確的翻譯值問題。我迄今爲止的代碼使用基本的三角函數計算給定旋轉的邊界框,然後將平移應用於旋轉矩陣。然而,我遇到的問題是,我的翻譯似乎總是出現1像素,我的意思是沿着旋轉圖像的頂部或兩側有一個1像素的黑色邊框。如何找到旋轉後的2D圖像點的翻譯值?

這裏是我的代碼:

def rotate_image(mat, angle): 
    height, width = mat.shape[:2] 
    image_center = (width/2.0, height/2.0) 
    rotation_mat = cv2.getRotationMatrix2D(image_center, angle, 1.0) 

    # Get Bounding Box 
    radians = math.radians(angle) 
    sin = abs(math.sin(radians)) 
    cos = abs(math.cos(radians)) 
    bound_w = (width * cos) + (height * sin) 
    bound_h = (width * sin) + (height * cos) 

    # Set Translation 
    rotation_mat[0, 2] += (bound_w/2.0) - image_center[0] 
    rotation_mat[1, 2] += (bound_h/2.0) - image_center[1] 

    rotated_mat = cv2.warpAffine(mat, rotation_mat, (int(bound_w), int(bound_h))) 
    return rotated_mat 

這裏作參考,原始圖像利用該代碼圖像的一些例子:

coffee.png - 原始 coffee.png – Original

coffee.png - 90° - 注意頂部的1px邊框 coffee.png - 90°

coffee.png - 180° - 請注意在頂部的1px寬的邊框和左 coffee.png - 1°

我不是我的數學這麼熱,但我大膽地說,這是由一些四捨五入問題引起猜測我們正在處理浮點數。 我想知道其他人使用什麼方法,請問什麼是最簡單和最高效的方式來旋轉和翻譯關於其中心點的圖像?

謝謝。

編輯

按@ Falko的回答,我沒有使用從零開始計算。我更正的代碼如下:

def rotate_image(mat, angle): 
    height, width = mat.shape[:2] 
    image_center = ((width - 1)/2.0, (height - 1)/2.0) 
    rotation_mat = cv2.getRotationMatrix2D(image_center, angle, 1.0) 

    # Get Bounding Box 
    radians = math.radians(angle) 
    sin = abs(math.sin(radians)) 
    cos = abs(math.cos(radians)) 
    bound_w = (width * cos) + (height * sin) 
    bound_h = (width * sin) + (height * cos) 

    # Set Translation 
    rotation_mat[0, 2] += ((bound_w - 1)/2.0 - image_center[0]) 
    rotation_mat[1, 2] += ((bound_h - 1)/2.0 - image_center[1]) 

    rotated_mat = cv2.warpAffine(mat, rotation_mat, (int(bound_w), int(bound_h))) 
    return rotated_mat 

我還是很欣賞看到人們用來執行旋轉和翻譯的替代方法! :)

回答

2

我想你的圖像中心是錯誤的。例如,一個4x4圖像的列0,1,2和3.然後你的中心計算爲4/2 = 2。但它應該是第1列和第2列之間的1.5。

所以你最好使用(寬度 - 1)/2.0和(高度-1)/2.0。

+0

當然!!我們從0,而不是1 ..我正在與矩陣,而不是像素!謝謝你指出! :)現在,我對中心點的寬度/高度以及bound_w/bound_h翻譯計算都做了-1。它適合!謝謝 – Robula