2017-08-16 304 views
0

我爲自己製作了一個小例子來玩弄OpenCV wrapPerspective,但輸出並不像我期望的那樣完全。OpenCV:瞭解warpPerspective /透視變換

我的輸入是一個45度角的酒吧。我想改變它,使它垂直對齊/成90°角。沒有問題。但是,我不明白的是,實際目的地點周圍的一切都是黑色的。我不明白這一點的原因是,實際上只有轉換矩陣被傳遞給wrapPerspective函數,而不是目標點本身。所以我的預期輸出將是一個90度角的棒,大部分是黃色而不是黑色。我在推理中的錯誤在哪裏?

# helper function 
def showImage(img, title): 
    fig = plt.figure() 
    plt.suptitle(title) 
    plt.imshow(img) 


# read and show test image 
img = mpimg.imread('test_transform.jpg') 
showImage(img, "input image") 


# source points 
top_left = [194,430] 
top_right = [521,103] 
bottom_right = [549,131] 
bottom_left = [222,458] 
pts = np.array([bottom_left,bottom_right,top_right,top_left]) 


# target points 
y_off = 400; # y offset 
top_left_dst = [top_left[0], top_left[1] - y_off] 
top_right_dst = [top_left_dst[0] + 39.6, top_left_dst[1]] 
bottom_right_dst = [top_right_dst[0], top_right_dst[1] + 462.4] 
bottom_left_dst = [top_left_dst[0], bottom_right_dst[1]] 
dst_pts = np.array([bottom_left_dst, bottom_right_dst, top_right_dst, top_left_dst]) 

# generate a preview to show where the warped bar would end up 
preview=np.copy(img) 
cv2.polylines(preview,np.int32([dst_pts]),True,(0,0,255), 5) 
cv2.polylines(preview,np.int32([pts]),True,(255,0,255), 1) 
showImage(preview, "preview") 


# calculate transformation matrix 
pts = np.float32(pts.tolist()) 
dst_pts = np.float32(dst_pts.tolist()) 
M = cv2.getPerspectiveTransform(pts, dst_pts) 

# wrap image and draw the resulting image 
image_size = (img.shape[1], img.shape[0]) 
warped = cv2.warpPerspective(img, M, dsize = image_size, flags = cv2.INTER_LINEAR) 
showImage(warped, "warped") 

使用該代碼的結果是:

enter image description here

這裏是我的輸入圖像test_transform.jpg: enter image description here 這裏是添加座標相同的圖像: enter image description here

根據要求,這裏是轉換矩陣:

[[ 6.05504680e-02 -6.05504680e-02 2.08289910e+02] 
[ 8.25714275e+00 8.25714275e+00 -5.12245707e+03] 
[ 2.16840434e-18 3.03576608e-18 1.00000000e+00]] 
+0

您可以輸出的轉換矩陣?我猜想有一些相當大的視角部分。如果您只想執行2D旋轉和平移(無透視部分的仿射變換),則最後一行應該是(0,0,1)。您可以通過將平移(旋轉中心設置爲0),圍繞(0,0)(有一定角度)旋轉以及使用另一個平移將中心移回原始位置或您想要對象的任何位置來計算2D旋轉放置。這些操作可以合併爲一個轉換矩陣。 – Micka

+0

@Micka:在我的初始文章結尾添加了轉換矩陣。其實這只是一個簡化的例子/測試,最後我想改變街道車道(汽車視角到鳥眼視角) –

回答

2

您在陣列或他們的位置排序可能是錯誤。檢查這個轉換後的圖像:dst_pts數組是:np.array([[196,492],[233,494],[234,32],[196,34]]),或多或少像預覽圖像中的藍色矩形。 (我做了自己的座標,以確保它們是正確的) 注:源和目標點應在正確的順序

enter image description here

+1

這是正確的答案。斜角條的「top_left」對應於垂直條的「bottom_left」(所有其他人都遵循同樣的錯誤)。這就是爲什麼垂直條的頂部和底部是模糊的,以及爲什麼OPs扭曲圖片中的黃色很窄。 –

+1

謝謝大家,你們兩個都對!對於我來說,固定的工作來源點是'top_left = [521,103] top_right = [549,131] bottom_right = [222,458] bottom_left = [194,430]'我調整了偏移量:'y_off = 50' –