Equation of a ray passing through the camera center and an image point

835 Views Asked by At

If C is the camera center in homogeneous world coordinates and x is a point on the image plane, the ray passing through C and x is said to be: $$ X(\lambda) = P^{+}x + \lambda C $$ where P is the camera matrix that maps world points to the image plane: $$ x = PX $$ $P^{+}$ is the pseudo inverse of the 3x4 camera matrix.

My question is this: Why is the above equation true?

Should it not be: $$ X(\lambda) = (1-\lambda)P^{+}x + \lambda C $$

Is it perhaps a consequence of homogeneous coordinates that: $$ X(\lambda) = X(\lambda)/(1-\lambda) = P^{+}x + \lambda C/(1-\lambda) $$

Then we can define $X(\lambda_2) = P^{+}x + \lambda_2 C$ where $\lambda_2 = \lambda/(1-\lambda) $

2

There are 2 best solutions below

1
On

The reason the answer I put in is not correct is because:

The x and C in the equation $X(\lambda) = P^+x + \lambda C$ are homogeneous vectors and don't live in $R^2$. You cannot get the direction of the line between x and C by subtracting the homogeneous representations of x and C. You get the line by doing a cross product instead. So the wrong derivation shown is a result of applying principles to homogeneous space that are incorrect. (Namely, the incorrect principle is that direction of a line between two points can be computed by subtracting the coordinates of the two points)

The derivation of $X(\lambda) = P^+x + \lambda C$ is a lot simpler than I thought it was and has nothing to do with finding directions of lines:

Consider a system $Ax = b$ where A is a 4x3 matrix.

To invert the relationship we initially find that $x = A^+b$. That is not the only solution though as A has a kernel of dimension one. The kernel is $\lambda C$. The set of solutions is then $x = A^+b + \lambda C$

To understand this a bit further, let us agree that we can change the coordinate systems of x and b in such a way that the only nonzero elements A has are on the diagonal. This will now look like:

$$\begin{bmatrix}b_1\\b_2\\b_3\end{bmatrix} = \begin{bmatrix}a & 0 & 0 & 0\\0 & b & 0 & 0\\0 & 0 & c & 0\end{bmatrix}\begin{bmatrix}x_1\\x_2\\x_3\\x_4\end{bmatrix}$$

It is now easy to see that to get x:

$$\begin{bmatrix}x_1\\x_2\\x_3\\x_4\end{bmatrix} = \begin{bmatrix}1/a & 0 & 0\\0 & 1/b & 0\\0 & 0 & 1/c\\0 & 0 &0\end{bmatrix}\begin{bmatrix}b_1\\b_2\\b_3\end{bmatrix} + \lambda \begin{bmatrix}0\\0\\0\\1\end{bmatrix}$$

The above looks nice because we were able to choose nice coordinate frames for x and b. We could now undo the transformation on the coordinate frames and get a map directly from x to b in their original frames.

0
On

This is confusing... but both:

$$ X(\lambda) = P^{+}x + \lambda C $$

$$ X(\lambda) = (1-\lambda)P^{+}x + \lambda C $$

Are rays that pass through P+x and C. First of all, the reason why this is so confusing is because, as you stated, these are homogeneous coordinates, not euclidean coordinates, so the intuition you use for adding euclidean vectors doesn't really hold up because after you add them, you need to divide by the last coordinate to bring them back to euclidean space, which is how the ray is defined (it's a line in euclidean space, but with homogenous coordinates).

Because this is so confusing, I just decided the easiest way to show this is correct is to just program it out and plot the results.

The first equation:

import numpy as np
import matplotlib.pyplot as plt

c = np.array([1,2,1]) # center
p = np.array([4,5,1]) # point

# Try out the equation `X(lambda) = p + lambda*c`
ls = np.linspace(-500, 500, 1000)
Xs_lambda = np.array([p + l*c for l in ls])

plt.plot(c[0]/c[2], c[1]/c[2], 'gs')
plt.plot(p[0]/p[2], p[1]/p[2], 'rs')
plt.plot(Xs_lambda[:,0]/Xs_lambda[:,2], Xs_lambda[:,1]/Xs_lambda[:,2], '-r')

Results in:

enter image description here

# Now try out the equation `X(lambda) = lambda*p + (1-lambda)*c`
ls = np.linspace(-1, 2, 1000)
Xs_lambda = np.array([l*p + (1-l)*c for l in ls])

plt.plot(c[0]/c[2], c[1]/c[2], 'gs')
plt.plot(p[0]/p[2], p[1]/p[2], 'rs')
plt.plot(Xs_lambda[:,0]/Xs_lambda[:,2], Xs_lambda[:,1]/Xs_lambda[:,2], '-r')

Results in:

enter image description here

These are both lines passing through P+x and C and parameterized by l.

Now, returning to the math in the 2D case, let:

$$ X = [x_1, x_2, 1] $$ $$ Y = [y_2, y_2, 1] $$

Now adding a linear combination of the two:

$$ k_1*X + k_2*Y $$ $$ [k_1*x1 + k_2*y_1, k_1*x_2 + k_2*y_2, k_1+k_2] $$

The resulting first coordinate in euclidean coordinates is now:

$$ (k_1*x_1 + k_2*y_1)/(k_1+k_2) $$

Simplifying further...

$$ (k_1/(k_1+k_2))*x_1 + (k_2/(k_1+k_2))*y_1 $$

So this means only the relative ratios between k_1 and k_2 matter and the resulting value is a linear combination of X and Y with coefficients that sum to 1, meaning it will form a line between X and Y as long as the relative ratio between k1 and k2 are varied which is true for both equations at the top.