首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在使用OpenCV warpPerspective时显示整个图像

如何在使用OpenCV warpPerspective时显示整个图像
EN

Stack Overflow用户
提问于 2012-10-25 14:57:17
回答 3查看 25.1K关注 0票数 25

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

图1:

图2:

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

代码语言:javascript
复制
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的完整图片?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-10-26 02:09:20

是的,但是你应该意识到输出的图像可能非常大。我快速编写了以下Python代码,但即使是3000 x 3000的图像也无法适应输出,由于转换的原因,它太大了。虽然,这是我的代码,但我希望它对您有用。

代码语言:javascript
复制
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)为例。

代码语言:javascript
复制
out_2 = cv.fromarray(np.zeros((3000,3000,3),np.uint8))

通过使用旧的cv接口,我直接写入输出,因此它不会被裁剪。我尝试过使用cv2接口,但由于某些原因它不起作用……也许有人能对此有所了解?

代码语言:javascript
复制
cv.WarpPerspective(cv.fromarray(im), out_2, cv.fromarray(h))
cv.ShowImage("test", out_2)
cv.SaveImage("result.png", out_2)
cv2.waitKey()

无论如何,这给出了一个非常大的图像,其中包含您的原始图像1,扭曲。如果将输出图像指定为足够大,则整个图像将可见。(这可能真的很大!)

我希望这段代码能对你有所帮助。

票数 9
EN

Stack Overflow用户

发布于 2013-12-03 23:46:57

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

代码语言:javascript
复制
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)

票数 49
EN

Stack Overflow用户

发布于 2016-11-01 07:12:30

首先,按照前面的解决方案计算单应矩阵。在获得单应矩阵之后,您需要相对于单应矩阵对图像进行扭曲。最后,合并变形后的图像。

在这里,我将分享另一个可以用来合并扭曲图像的想法。(前面的答案,使用了一系列索引来覆盖,这里我使用ROI的掩蔽)

用黑色遮罩感兴趣区域(ROI)和图像。然后添加具有ROI的图像。(参见OpenCV Bitmask Tutorial)

代码语言:javascript
复制
def copyOver(source, destination):
    result_grey = cv2.cvtColor(source, cv2.COLOR_BGR2GRAY)
    ret, mask = cv2.threshold(result_grey, 10, 255, cv2.THRESH_BINARY)
    mask_inv = cv2.bitwise_not(mask)
    roi = cv2.bitwise_and(source, source, mask=mask)
    im2 = cv2.bitwise_and(destination, destination, mask=mask_inv)
    result = cv2.add(im2, roi)
    return result


warpedImageB = cv2.warpPerspective(imageB, H, (imageA.shape[1], imageA.shape[0]))
result = copyOver(imageA, warpedImageB)

第一张图片:

第二张图片:

拼接后的图像:

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13063201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档