2017-08-16 266 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' –