我试图找到变换矩阵H,这样我就可以乘以(x,y)像素坐标并获得(x,y)真实世界坐标。这是我的代码:
import cv2
import numpy as np
from numpy.linalg import inv
if __name__ == '__main__' :
D=[159.1,34.2]
I=[497.3,37.5]
G=[639.3,479.7]
A=[0,478.2]
# Read source image.
im_src = cv2.imread('/home/vivek/june_14.png')
# Four corners of the book in source image
pts_src = np.array([D,I,G,A])
# Read destination image.
im_dst = cv2.imread('/home/vivek/june_14.png')
# Four corners of the book in destination image.
print "img1 shape:",im_dst.shape
scale=1
O=[0.0,0.0]
X=[134.0*scale,0]
Y=[0.0,184.0*scale]
P=[134.0*scale,184.0*scale]
# lx = 75.5 * scale
# ly = 154.0 * scale
pts_dst = np.array([O,X,P,Y])
# Calculate Homography
h, status = cv2.findHomography(pts_src, pts_dst)
print "homography:",h
print "inv of H:",inv(h)
print "position of the blob on the ground xy plane:",np.dot(np.dot(h,np.array([[323.0],[120.0],[1.0]])),scale)
# Warp source image to destination based on homography
im_out = cv2.warpPerspective(im_src, h, (im_dst.shape[1],im_dst.shape[0]))
# Display images
cv2.imshow("Source Image", im_src)
cv2.imshow("Destination Image", im_dst)
cv2.imshow("Warped Source Image", im_out)
cv2.imwrite("im_out.jpg", im_out)
cv2.waitKey(0)
我得到的全球xy非常关闭。我在某处做错了吗?
答案 0 :(得分:6)
Homographies是3x3
矩阵,而点只是成对,2x1
,所以没有办法将这些映射到一起。相反,使用齐次坐标,使3x1
向量相乘。但是,同一点可以在表示同一点时进行缩放;也就是说,在齐次坐标系中,(kx,ky,k)与(x,y,1)的点相同。来自Wikipedia page on homogeneous coordinates:
在欧几里得平面上给出一个点(x,y),对于任何非零实数 Z ,三元(xZ,yZ,Z )被称为该点的一组齐次坐标。根据这个定义,将三个齐次坐标乘以一个共同的非零因子,为同一点提供一组新的齐次坐标。特别是,(x,y,1)是点(x,y)的均匀坐标系统。例如,笛卡尔点(1,2)可以在齐次坐标中表示为(1,2,1)或(2,4,2) 。通过将前两个位置除以第三个位置来恢复原始笛卡尔坐标。因此,与笛卡尔坐标不同,单个点可由无限多个齐次坐标表示。
显然,在笛卡尔坐标系中,这种缩放不成立; (x,y)与(xZ,yZ)不同,除非 Z = 0 或 Z = 1 。因此,我们需要一种方法来映射这些齐次坐标,这些坐标可以无限多种方式表示,直到笛卡尔坐标,只能用一种方式表示。幸运的是,这很简单,只需缩放齐次坐标,使三元组中的最后一个数字 1 。
Homographies乘以齐次坐标并返回齐次坐标。因此,为了将它们映射回笛卡尔世界,您只需要除以最后一个坐标来缩放它们,然后将前两个数字翻出来。
当您通过单应性乘以齐次坐标时,需要缩放它们:
sx' x
sy' = H * y
s 1
因此,为了回到笛卡尔坐标,将新的齐次坐标除以 s :(sx',sy',s)/ s =(x' ,y',1)然后(x',y')是您想要的点。
使用内置的OpenCV函数convertPointsFromHomogeneous()
将点从均匀的3向量转换为笛卡尔2向量。
答案 1 :(得分:0)
# convert to world coordinates
def toworld(x,y):
imagepoint = [x, y, 1]
worldpoint = np.array(np.dot(inversehomographymatrix,imagepoint))
scalar = worldpoint[0,2]
xworld = int((worldpoint[0][0]/scalar)*10 +p.x_buffer_width*10)
yworld = int((worldpoint[0][1]/scalar)*10 +p.y_buffer_width*10) #in 10demm
return xworld, yworld