使用OpenCV warpPerspective时如何显示整个图像
computer-vision
image-processing
numpy
opencv
25
0

我这里有2张测试图像。我的问题是,如何在不裁剪图像的情况下将第一个图像中的正方形映射到第二个图像中的四边形。

图片1 图片1

图片2: 图片2

这是我当前使用openCV warpPerspective函数的代码。

import cv2
import numpy as np

img1_square_corners = np.float32([[253,211], [563,211], [563,519],[253,519]])
img2_quad_corners = np.float32([[234,197], [520,169], [715,483], [81,472]])

h, mask = cv2.findHomography(img1_square_corners, img2_quad_corners)
im = cv2.imread("image1.png")
out = cv2.warpPerspective(im, h, (800,800))
cv2.imwrite("result.png", out)

结果: 结果

如您所见,由于warpPerspective函数中的dsize =(800,800)参数,我无法获得图像1的完整视图。如果调整dsize,则正方形将无法正确映射。有什么方法可以调整输出图像的大小,以便获得图像1的全图?

参考资料:
Stack Overflow
收藏
评论
共 2 个回答
高赞 时间 活跃

我的解决方案是计算结果图像的大小,然后进行翻译。

def warpTwoImages(img1, img2, H):
    '''warp img2 to img1 with homograph H'''
    h1,w1 = img1.shape[:2]
    h2,w2 = img2.shape[:2]
    pts1 = float32([[0,0],[0,h1],[w1,h1],[w1,0]]).reshape(-1,1,2)
    pts2 = float32([[0,0],[0,h2],[w2,h2],[w2,0]]).reshape(-1,1,2)
    pts2_ = cv2.perspectiveTransform(pts2, H)
    pts = concatenate((pts1, pts2_), axis=0)
    [xmin, ymin] = int32(pts.min(axis=0).ravel() - 0.5)
    [xmax, ymax] = int32(pts.max(axis=0).ravel() + 0.5)
    t = [-xmin,-ymin]
    Ht = array([[1,0,t[0]],[0,1,t[1]],[0,0,1]]) # translate

    result = cv2.warpPerspective(img2, Ht.dot(H), (xmax-xmin, ymax-ymin))
    result[t[1]:h1+t[1],t[0]:w1+t[0]] = img1
    return result

dst_pts = float32([kp1[m.queryIdx].pt for m in good]).reshape(-1,1,2)
src_pts = float32([kp2[m.trainIdx].pt for m in good]).reshape(-1,1,2)
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)

result = warpTwoImages(img1_color, img2_color, M)

在此处输入图片说明

收藏
评论

是的,但是您应该意识到输出图像可能非常大。我很快编写了以下Python代码,但是即使是3000 x 3000的图像也无法满足输出要求,由于转换,它太大了。尽管这是我的代码,但我希望它对您有用。

import cv2
import numpy as np
import cv           #the old cv interface

img1_square_corners = np.float32([[253,211], [563,211], [563,519],[253,519]])
img2_quad_corners = np.float32([[234,197], [520,169], [715,483], [81,472]])

h, mask = cv2.findHomography(img1_square_corners, img2_quad_corners)
im = cv2.imread("image1.png")

在这里创建输出图像,我以(3000,3000)为例。

out_2 = cv.fromarray(np.zeros((3000,3000,3),np.uint8))

通过使用旧的cv接口,我直接写入了输出,因此不会被裁剪。我使用cv2接口尝试了此操作,但由于某种原因它无法正常工作……也许有人可以对此有所了解?

cv.WarpPerspective(cv.fromarray(im), out_2, cv.fromarray(h))
cv.ShowImage("test", out_2)
cv.SaveImage("result.png", out_2)
cv2.waitKey()

无论如何,这会产生非常大的图像,其中包含您的原始图像1(变形)。如果您指定输出图像足够大,则整个图像将可见。 (确实可能很大!)

希望这段代码对您有所帮助。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题