Trying to convert pinhole world coordinates x,y,z to pixel x,y, or grid reference n

coordinate systemsgeometryplane-geometry

TLDR; This in plain English enter image description here
where y1 and y2 become the x,y coordinates derived from the x1,x2,x3 (x,y,z centroid coordinates)

x: -379
Y: -1445
z: 3250

My first question here, please be kind.

I'm trying to figure out the math conversion from a World coordinates Centroid to x,y pixel coordinates (e.g. 3,2)

x,y 1 2 3 4
1
2 3,2
3
4

and then to a grid reference (e.g 8)

grid
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19

So onto my actual figures I have a 3 coordinates labeled as "centroid" – these represent the center of an entity detected by A.I. They use the Pinhole Camera world coordinates.

x: -379
Y: -1445
z: 3250

I also have an arbitrary length set of pixel based x, y coordinates labelled as "pos2d" – these will be close to the centroid coordinates (for correlation) – the centroid on the pixel coordinates will be close to these coordinates.

x: 4892,
y: 4089

x: 4196,
y: 3428

x: 4250,
y: 2982

For a frame of reference: The pixel image coordinate are always 10,000 by 10,000

I've been trying to find a way to convert the centroid into pixels so I can then convert that quite easily to a grid reference. If there is any shortcut to going from centroid direct to grid reference that would be a bonus.

I believe this formula to be correct however I've not managed to implement it consistently.

I believe this formula to be correct

Where x,y,z becomes u,v (x,y pixel coordinates)

I'm really struggling, if anyone can help.

Unfortunately I can neither read nor write complex formulas with matrices so if this can be done with basic math that would be appreciated.

In essence I need to convert the centroid coordinate system to the pos2d coordinate system.

Full data follows
[{
    Centroid: {
      x: -5968,
      y: -36,
      z: 3250
    },
    Pos2D:
    [{
        x: 2071,
        y: 5089
      }, {
        x: 1303,
        y: 5125
      }, {
        x: 1232,
        y: 5107
      }, {
        x: 1107,
        y: 5035
      }, {
        x: 1107,
        y: 4892
      }, {
        x: 1232,
        y: 4821
      }, {
        x: 1303,
        y: 4821
      }, {
        x: 2071,
        y: 4857
      }
    ],
  }, {
    Centroid: {
      x: -5796,
      y: 444,
      z: 3250
    },
    Pos2D:
    [{
        x: 2125,
        y: 5339
      }, {
        x: 1410,
        y: 5428
      }, {
        x: 1321,
        y: 5410
      }, {
        x: 1196,
        y: 5357
      }, {
        x: 1196,
        y: 5196
      }, {
        x: 1303,
        y: 5125
      }, {
        x: 2000,
        y: 5089
      }, {
        x: 2107,
        y: 5089
      }
    ],
  }, {
    Centroid: {
      x: -6118,
      y: -66,
      z: 3250
    },
    Pos2D:
    [{
        x: 2035,
        y: 5071
      }, {
        x: 1267,
        y: 5089
      }, {
        x: 1196,
        y: 5089
      }, {
        x: 1089,
        y: 5017
      }, {
        x: 1089,
        y: 4875
      }, {
        x: 1196,
        y: 4821
      }, {
        x: 1285,
        y: 4803
      }, {
        x: 2035,
        y: 4839
      }
    ],
  }, {
    Centroid: {
      x: -5890,
      y: 454,
      z: 3250
    },
    Pos2D:
    [{
        x: 2089,
        y: 5339
      }, {
        x: 1375,
        y: 5428
      }, {
        x: 1303,
        y: 5410
      }, {
        x: 1178,
        y: 5357
      }, {
        x: 1178,
        y: 5214
      }, {
        x: 1285,
        y: 5125
      }, {
        x: 1964,
        y: 5089
      }, {
        x: 2089,
        y: 5107
      }
    ],
  }
]

My incomplete implementation of the above formula was exceptionally close however on occasion it would reflect the centroid coordinates to the oppose side of the Cartesian plane.

Best Answer

I think this is the correct interpretation of what you're doing:

You have a pinhole (?centroid?) located at $(x_p,y_p,z_p)$ and you are projecting onto a plane perpendicular to the $z$-direction. That plane located $f$ units (in the negative $z$-direction) from the pinhole.

Let's find the $(u,v)$ coordinates of an arbitrary point $(x_c,y_c,z_c)$.

First, find the line through $(x_c,y_c,z_c)$ and $(x_p,y_p,z_p)$. This line has direction vector ${\bf v} = \langle x_c-x_p, y_c-y_p, z_c-z_p\rangle$ and passes through the point $(x_p,y_p,z_p)$. We get that ${\bf \ell}(t) = \langle x_p,y_p,z_p \rangle + t\langle x_c-x_p, y_c-y_p, z_c-z_p\rangle$ parameterizes such a line.

Multiplying out: ${\bf \ell}(t) = \langle x_p+t(x_c-x_p),y_p+t(y_c-y_p),z_p+t(z_c-z_p)\rangle$. We want the point on this line which lies in the plane perpendicular to the $z$-direction and $f$ units away from $(x_p,y_p,z_p)$. In other words, the $z$-coordinate of our projected point should be $z_p - f$.

Therefore, we need $z_p+t(z_c-z_p)=z_p-f$ so that $t(z_c-z_p)=-f$ and so $t = \dfrac{-f}{z_c-z_p}$. Thus the $x=u$ and $y=v$ coordinates of that point are $u = x_p+\dfrac{-f}{z_c-z_p}(x_c-x_p)$ and $v = y_p+\dfrac{-f}{z_c-z_p}(y_c-y_p)$.

Your formulas come from the case when $(x_p,y_p,z_p)=(0,0,0)$ (i.e., the origin).

So to convert from the 3D-coordinates to the 2D-projected coordinates, you just need to compute: $$(x_c,y_c,z_c) \mapsto \left( x_p+\dfrac{-f}{z_c-z_p}(x_c-x_p), y_p+\dfrac{-f}{z_c-z_p}(y_c-y_p)\right)$$ [which is necessarily undefined when $z_c=z_p$]

I'm not sure what else there is to be said without you further specifying what you're doing.