Opencv单应性从像素xy坐标中查找全局xy坐标 [英] Opencv homography to find global xy coordinates from pixel xy coordinates

查看:338
本文介绍了Opencv单应性从像素xy坐标中查找全局xy坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到变换矩阵H,以便可以将(x,y)像素坐标相乘并获得(x,y)真实世界坐标.这是我的代码:

I am trying to find the transformation matrix H so that i can multiply the (x,y) pixel coordinates and get the (x,y) real world coordinates. Here is my code:

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非常不理想.我在某处做错了吗?

The global xy's i am getting are very off. Am i doing something wrong somewhere?

推荐答案

长答案

单应性是3x3矩阵,点是成对的2x1,因此无法将它们映射在一起.取而代之的是,使用齐次坐标,给出3x1个向量相乘.但是,在表示同一个点时,可以缩放同构点.也就是说,在同构坐标系中,(kx,ky,k)(x,y,1)相同.从关于同质坐标的维基百科页面:

The long answer

Homographies are 3x3 matrices and points are just pairs, 2x1, so there's no way to map these together. Instead, homogeneous coordinates are used, giving 3x1 vectors to multiply. However, homogeneous points can be scaled while representing the same point; that is, in homogeneous coordinates, (kx, ky, k) is the same point as (x, y, 1). From the Wikipedia page on homogeneous coordinates:

在欧几里得平面上给出一个点(x,y),对于任何非零实数 Z ,三元组(xZ,yZ,Z )称为该点的一组同类坐标.通过此定义,将三个齐次坐标乘以一个公共的非零因子就可以得出同一点的一组新的齐次坐标.特别是(x,y,1)是这样的点(x,y)的齐次坐标系.例如,笛卡尔点(1,2)可以用齐次坐标表示为(1、2、1)(2、4、2) .通过将前两个位置除以第三个位置可恢复原始笛卡尔坐标.因此,与笛卡尔坐标不同,单个点可以用无限多的齐次坐标表示.

Given a point (x, y) on the Euclidean plane, for any non-zero real number Z, the triple (xZ, yZ, Z) is called a set of homogeneous coordinates for the point. By this definition, multiplying the three homogeneous coordinates by a common, non-zero factor gives a new set of homogeneous coordinates for the same point. In particular, (x, y, 1) is such a system of homogeneous coordinates for the point (x, y). For example, the Cartesian point (1, 2) can be represented in homogeneous coordinates as (1, 2, 1) or (2, 4, 2). The original Cartesian coordinates are recovered by dividing the first two positions by the third. Thus unlike Cartesian coordinates, a single point can be represented by infinitely many homogeneous coordinates.

很显然,在笛卡尔坐标系中,这种缩放不成立. (x,y)(xZ,yZ)的点不同,除非 Z = 0 Z = 1 .因此,我们需要一种方法来映射这些齐次坐标(可以用无数种方法表示),直达只能用一种方法表示的笛卡尔坐标.幸运的是,这非常容易,只需缩放齐次坐标即可,因此三元组中的最后一个数字为 1 .

Obviously, in cartesian coordinates, this scaling does not hold; (x, y) is not the same point as (xZ, yZ) unless Z = 0 or Z = 1. So we need a way to map these homogeneous coordinates, which can be represented an infinite number of ways, down to Cartesian coordinates, which can only be represented one way. Luckily this is very easy, just scale the homogeneous coordinates so the last number in the triple is 1.

单应性会乘以齐次坐标,并返回齐次坐标.因此,为了将它们映射回笛卡尔世界,您只需要按最后一个坐标除以缩放它们,然后将前两个数字撕掉即可.

Homographies multiply homogeneous coordinates and return homogeneous coordinates. So in order to map them back to Cartesian world, you just need to divide by the last coordinate to scale them and then rip the first two numbers out.

将同构坐标乘以单应性时,需要缩放它们:

When you multiply homogeneous coordinates by a homography, you need to scale them:

sx'       x
sy' = H * y
s         1

因此,要返回笛卡尔坐标,请将新的齐次坐标除以 s :(sx',sy',s)/s =(x',y',1) 然后是(x',y')是您想要的点.

So to get back to Cartesian coordinates, divide the new homogeneous coordinates by s: (sx', sy', s)/s = (x', y', 1) and then (x', y') are the points you want.

使用内置的OpenCV函数 convertPointsFromHomogeneous() 可以将点从同类3向量转换为笛卡尔2向量.

Use the built-in OpenCV function convertPointsFromHomogeneous() to convert your points from homogeneous 3-vectors to Cartesian 2-vectors.

这篇关于Opencv单应性从像素xy坐标中查找全局xy坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆