3
$\begingroup$

Assume that I have a 3D circle with a center at $(c_1, c_2, c_3)$ in the circle coordinate frame $C$. The radius of the circle is $r$, and there is a unit vector $(v_1, v_2, v_3)$ (also in coordinate frame $C$) normal to the plane of the circle at the center point.

I have a pinhole camera located at point $(k_1, k_2, k_3)$ in the camera coordinate frame $K$. I have a known camera-to-circle transformation matrix $T_{C}^{K}$ that transforms any point in $C$ to coordinate frame $K$. The camera has a known intrinsic camera matrix $N$.

How do I project the 3D circle onto the image plane of the camera in order to find the parameters of the resulting ellipse / line segment / curve in the image plane.

$\endgroup$
4
  • 1
    $\begingroup$ Choose another notation than $I$ for the intrinsic camera matrix, since $I$ usually denotes the identity matrix. $\endgroup$ Feb 7 at 8:05
  • $\begingroup$ Are you asking for the parameters of the resulting ellipse? (I believe you can get a parabola as well) $\endgroup$
    – Alex K
    Feb 8 at 1:50
  • $\begingroup$ Thanks @AlexK. Yes, clarified. Would like the parameters of the projected curve / line segment / point in the image plane. $\endgroup$ Feb 8 at 18:55
  • $\begingroup$ Thanks @ChristopheLeuridan edited post. $\endgroup$ Feb 8 at 18:55

1 Answer 1

1
+50
$\begingroup$

Coordinate frames:

Let $\vec{p}_{c}=(x_c, \ y_c, \ z_c)$ be a point in the coordinate frame $C$ and $\vec{p}_{k}=(x_k, \ y_k, \ z_k)$ the same point in the coordinate frame $K$. The way we transform one point to another is by a $3 \times 3$ matrix $T_{ck}$ such

$$\vec{p}_{k} = T_{ck} \cdot \vec{p}_{c} + \vec{s}_{k}$$

The vector $\vec{s}_{k}$ is position of the origin $O_{c}$ on $K$.

The same happens for the camera: There's a transformation matrix $T_{kn}$ to transform a point $\vec{p}_{k} \in K$ to the point $\vec{p}_{n} \in N$

$$\vec{p}_{n} = T_{kn} \cdot \vec{p}_{k} + \vec{h}_{n}$$

For the camera, the origin $O_{k}$ is represented at the position $\vec{h}_{n}$.

Therefore, transforming any point $\vec{p}_{c}$ to a point $\vec{p}_{n}$ is made by

$$\vec{p}_{n} = \vec{h}_{n} + T_{kn} \cdot \vec{s}_{k} + T_{kn} T_{ck} \cdot \vec{p}_{c}$$

Lose information:

In the coordinate frame $K$, there's a point $\vec{k}_{k} = \left(k_1, \ k_2, \ k_3\right)$, which we call the pin-hole. The pin-hole camera always loses information. Let $\vec{n}_{k}$ be a unit vector perpendicular to the plane of the camera.

All the points that lie on the line $\vec{p}_{k} = \vec{k}_{k} + t \cdot \vec{n}_{k}$ are the same for the camera. So

$$\begin{align}\vec{p}_{n} & = \vec{h}_{n} + T_{kn} \cdot \vec{p}_{k} \\ & = \vec{h}_{n} + T_{kn} \cdot \left(\vec{k}_{k} + t \cdot \vec{n}_{k} \right) \\ & = \vec{h}_{n} + T_{kn} \cdot \vec{k}_{k} + t \cdot T_{kn} \cdot \vec{n}_{k}\end{align}$$

$$\boxed{T_{kn} \cdot \vec{n}_{k} = \vec{0}}$$

Normally that happens cause $T_{nk}$ normally is a transformation from $\mathbb{R}^{3}$ into $\mathbb{R}^{2}$:

$$T_{nk} = \begin{bmatrix}\vec{a}_{k} \\ \vec{b}_{k} \end{bmatrix} = \begin{bmatrix}a_1 & a_2 & a_ 3 \\ b_1 & b_2 & b_3 \end{bmatrix}$$ $$\langle \vec{a}_{k}, \vec{n}_{k}\rangle = 0 \ \ \ \ \ \ \text{and} \ \ \ \ \ \ \ \ \langle \vec{b}_{k}, \vec{n}_{k}\rangle = 0$$

Therefore, we can transform a point $\vec{p}_{k}$ into $\vec{q}_{k}$ by taking out the projection to the line at first.

$$\vec{q}_{k} = \underbrace{\dfrac{\langle \vec{a}_{k}, \ \vec{p}_{k}\rangle}{\langle \vec{a}_k, \ \vec{a}_{k} \rangle }}_{\alpha} \cdot \vec{a}_{k} + \underbrace{\dfrac{\langle \vec{b}_{k}, \ \vec{p}_{k}\rangle}{\langle \vec{b}_k, \ \vec{b}_{k} \rangle }}_{\beta} \cdot \vec{b}_{k}$$

And for $\vec{q}_{n}$ we get

$$\vec{q}_{n} = \vec{h}_{n} + T_{kn} \cdot \left(\alpha \cdot \vec{a}_{k} + \beta \cdot \vec{b}_{k}\right)$$

$$\begin{bmatrix}q_{n1} \\ q_{n2}\end{bmatrix} = \begin{bmatrix}h_{n1} \\ h_{n2}\end{bmatrix} + \underbrace{\begin{bmatrix}1 & \dfrac{\langle \vec{b}_{k}, \ \vec{a}_{k}\rangle}{\langle \vec{b}_k, \ \vec{b}_{k} \rangle } \\ \dfrac{\langle \vec{a}_{k}, \ \vec{b}_{k}\rangle}{\langle \vec{a}_k, \ \vec{a}_{k} \rangle } & 1\end{bmatrix}}_{H_k}\begin{bmatrix}\langle \vec{a}_{k}, \ \vec{p}_{k}\rangle\\ \langle \vec{b}_{k}, \ \vec{p}_{k}\rangle\end{bmatrix}$$

The circle:

There's a circle which center is given by $\vec{c}_{c} = (c_1, \ c_2, \ c_3)$ and has radius $r$. Its perpendicular vector (to the plane which contains the circle) is $\vec{v}_{c} = (v_1, \ v_2, \ v_3)$.

Let $\vec{g}_c$ be a point in the circle, then

$$\|\vec{g}_{c} - \vec{c}_{c}\| = r\label{1}\tag{1}$$ $$\left(\vec{g}_{c} - \vec{c}_{c}\right) \times \vec{v}_{c} = \vec{0}\label{2}\tag{2}$$

Now, let's call $\vec{u}_c$ and $\vec{w}_c$ two unit vectors that are parallel to the plane of the circle, such

$$\vec{u}_c \perp \vec{w}_c \perp \vec{v}_c \perp \vec{u}_c$$ $$\|\vec{u}_c\| = 1 \ \ \ \ \ \ \ \ \ \|\vec{w}_c\| = 1$$

From \eqref{1} and \eqref{2}

$$\vec{g}_{c} = \vec{c}_c + \vec{u}_{c} \cdot r\cos \theta + \vec{w}_c \cdot r\sin \theta$$

Transforming to $N$:

$$\begin{align}\vec{g}_{n} & = \vec{h}_{n} + T_{kn} \cdot \vec{s}_{k} + T_{kn} T_{ck} \cdot \vec{g}_{c} \\ & = \vec{h}_{n} + T_{kn} \cdot \vec{s}_{k} + T_{kn} T_{ck} \cdot \vec{c}_{c} + r \cos \theta \cdot T_{kn} T_{ck} \cdot \vec{u}_{c} + r \sin \theta \cdot T_{kn} T_{ck} \cdot \vec{w}_{c}\end{align}$$

Renaming

$$\vec{g}_{n} = \vec{f}_{n} + r \cos \theta \cdot \vec{u}_{n} + r \sin \theta \cdot \vec{w}_{n}$$

With

$$\begin{align*}\vec{f}_{n} & = \vec{h}_{n} + T_{kn} \cdot \left( \vec{s}_{k} + T_{ck} \cdot \vec{c}_{c}\right) \\ \vec{u}_{n} & = T_{kn} T_{ck} \cdot \vec{u}_{c} \\ \vec{w}_{n} & = T_{kn} T_{ck} \cdot \vec{w}_{c} \end{align*}$$

Then you will get an ellipse of center $\vec{f}_n$ and axis $\vec{u}_n$ and $\vec{w}_{n}$. If one of this two vectors are zero, then you will get a line.

There's a python code below to represent a projection from a 3D space to a 2D space (of camera) using the coordinates. The symbol @ represents matrix multiplication.

import numpy as np
from matplotlib import pyplot as plt
Tck = np.array([[1, 0, 0],
                [0, 1, 0],
                [0, 0, 1]])
Tkn = np.array([[1, 0, 1],
                [0, 1, 0]])
cc = [0, 0, 1]
uc = [1, 0, 0]
wc = [0, 1, 1]
sk = [0, 1, 0]
hn = [0, 1]
r = 1
uc /= np.linalg.norm(uc)
wc /= np.linalg.norm(wc)

cn = Tkn @ Tck @ cc
sn = Tkn @ sk
fn = hn + sn + cn
un = Tkn @ Tck @ uc
wn = Tkn @ Tck @ wc

theta = np.linspace(0, 2*np.pi, 129)
gnx = fn[0] + r * np.cos(theta) * un[0] + r * np.sin(theta) * wn[0]
gny = fn[1] + r * np.cos(theta) * un[1] + r * np.sin(theta) * wn[1]

plt.plot(gnx, gny, label="circle on C")
plt.scatter(cn[0], cn[1], label="origin of C")
plt.scatter(sn[0], sn[1], label="origin of K")
plt.axis("equal")
plt.legend()
plt.show()
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .