Raf*_*him 17 python opencv numpy image-processing computer-vision
我这里有2个测试图像.我的问题是,如何将第一张图像中的正方形映射到第二张图像中的四边形而不裁剪图像.
图1:
图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)
Run Code Online (Sandbox Code Playgroud)
结果:
如您所见,由于warpPerspective函数中的dsize =(800,800)参数,我无法获得图像1的完整视图.如果我调整dsize,则方形将无法正确映射.有没有办法调整输出图像的大小,以便我可以获得图像1的全貌?
arc*_*fox 36
我的解决方案是计算结果图像大小,然后进行翻译.
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)
Run Code Online (Sandbox Code Playgroud)
是的,但您应该意识到输出图像可能非常大.我很快写了下面的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")
Run Code Online (Sandbox Code Playgroud)
在这里创建一个输出图像,我用(3000,3000)作为例子.
out_2 = cv.fromarray(np.zeros((3000,3000,3),np.uint8))
Run Code Online (Sandbox Code Playgroud)
通过使用旧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()
Run Code Online (Sandbox Code Playgroud)
无论如何,这会产生一个非常大的图像,其中包含原始图像1,扭曲.如果指定输出图像足够大,则整个图像将可见.(确实可能非常大!)
我希望这段代码可以帮到你.