2013-07-17 32 views
4

我想从一个梯形(在第一个图像)到一个矩形(在第二个图像),但得到一个奇怪的结果(在第三个图像)。OpenCV透视变换给予意想不到的效果

enter image description here

我的计划是使用透视变换,通过梯形的四个拐角点和矩形的四个角点限定。

在这个例子中,对于梯形它们是:

ptsTrap = [[ 50.   100.  ] 
      [ 50.   200.  ] 
      [ 250.   64.73460388] 
      [ 250.   235.26539612]] 

和用于矩形:

ptsRect = [[ 50. 100.] 
      [ 50. 200.] 
      [ 250. 100.] 
      [ 250. 200.]] 

我得到一个透视从这些点变换:

T = cv2.getPerspectiveTransform(ptsTrap, ptsRect) 

然后从那里建立图像:

arrTrapToRect = cv2.warpPerspective(arrTrap, T, arrTrap.shape[:2]) 

但是,正如您从图像中看到的,这并没有给出预期的转换。

我似乎无法弄清楚为什么即使定义转换的点也没有按照它进行投影。有任何想法吗?

回答

7

您的方法是正确的。当您指定角点的坐标时会出现问题。我不知道你如何计算它们,但是你已经交换了X轴和Y轴。这反映在应用于最终图像的转换中。我找到的角点是:

ptsTrap = [[[ 99. 51.]] 
      [[ 64. 251.]] 
      [[ 234. 251.]] 
      [[ 199. 51.]]] 

ptsRect = [[[ 102. 49.]] 
      [[ 100. 249.]] 
      [[ 200. 250.]] 
      [[ 200. 50.]]] 

寻找角度,从这些点变换给出正确的结果: Perspective Transform result

供参考,这是我使用的代码:

import cv2 
import numpy as np 

def find_corners(image): 
    im = cv2.Canny(image, 100, 200) 

    cnt = cv2.findContours(im,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[0] 
    cnt = cv2.approxPolyDP(cnt[0], 5, True) 
    return cnt.astype(np.float32) 

def main(argv): 
    trap = cv2.imread('trap.png', cv2.IMREAD_GRAYSCALE) 
    rect = cv2.imread('rect.png', cv2.IMREAD_GRAYSCALE) 

    ptsTrap = find_corners(trap) 
    ptsRect = find_corners(rect) 

    T = cv2.getPerspectiveTransform(ptsTrap, ptsRect) 

    warp = cv2.warpPerspective(trap, T, rect.shape[:2]) 

    cv2.imshow('', warp) 
    cv2.imwrite('warp.png', warp) 
    cv2.waitKey() 
    cv2.destroyAllWindows() 
+0

谢谢那确实是问题所在。我自己在制作图片,而我犯了愚蠢的错误,把x,y当作我,j而不是j,i。现在看起来不错! – sapi