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:
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.
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.
The short answer
When you multiply homogeneous coordinates by a homography, you need to scale them:
sx' x
sy' = H * y
s 1
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.
The shorter answer
Use the built-in OpenCV function convertPointsFromHomogeneous()
to convert your points from homogeneous 3-vectors to Cartesian 2-vectors.