# Calculate X Y in mm with known Z

**URL:** <https://forum.opencv.org/t/calculate-x-y-in-mm-with-known-z/5732>\
**Category:** C++\
**Tags:** calib3d, fisheye\
**Created:** [October 20, 2021, 9:54am UTC](https://forum.opencv.org/t/calculate-x-y-in-mm-with-known-z/5732 "2021-10-20T09:54:33Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![meoDz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/meodz/32/1684_2.png) [@meoDz](https://forum.opencv.org/u/meoDz)\
**Post date:** [October 20, 2021, 9:54am UTC](https://forum.opencv.org/t/calculate-x-y-in-mm-with-known-z/5732/1 "2021-10-20T09:54:33Z")

</div>

Hi all,

I am using the fisheye camera to measure X, Y dimensions with the known Z as can be demonstrated in the image.

 ![System](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/1/12314aea1830c6a270f346d8789ad836235221a4.jpeg)

The fisheye camera is calibrated by putting the checkboard on the table. After calibration, I have camera matrix, distortion, rotation vector, and translation vector. Z dimension is took from translation vector [a,b, Z].  
Note: the checkboard is 6 x 8 and for each square: 20mm x 20mm

Now, I would like to measure the **X ,Y dimension** in the **mm** unit of **Point A** but I have wrong result.  
I used **undisortPoint()** with the input is: **uncalibrated image point(u,v)** from fisheyecamera. Then, I used this equation to calculate **X ,Y dimension** in the **mm** unit

- u = f\_{x} \* X / Z
- v = f\_{y} \* Y / Z

However, the result of **Point A(X, Y)** is wrong.

My question is:

1. undisortPoint() returns the point in optical Point coordinate or image coordinate?
2. Is there any problem with my process that affects my X Y result?

Thank you very much.  
I really apologize for my terrible English. Please forgive me.

---

<div class="post-metadata">

**Author:** ![Steve\_in\_Denver](https://avatars.discourse-cdn.com/v4/letter/s/eada6e/32.png) [@Steve\_in\_Denver](https://forum.opencv.org/u/Steve_in_Denver)\
**Post date:** [October 20, 2021, 8:32pm UTC](https://forum.opencv.org/t/calculate-x-y-in-mm-with-known-z/5732/2 "2021-10-20T20:32:19Z")

</div>

undistorPoint() converts distorted image coordinates to undistorted image coordinates. If you use f as your z-cooridnate you will have a 3-D point in the camera coordinates (in units of pixels).

It looks like part of the problem is that you aren’t accounting for the rotation and translation of the camera in table coordinates. If you compute your camera position in world coords and the vector corresponding to your image point also in world coords you can compute a ray/plane intersection with your world plane.

I think something like:

```auto
cv::Mat R;
cv::Rodrigues(rvec,R);
cv::Mat cameraCoordsOfImagePoint = cv::Mat(3,1); // load this with Ux, Uy, F
cv::Mat worldTrans = -R.inv() * tvec;
cv::Mat worldVec = R.inv() * cameraCoordsOfImagePoint;

// the image ray in world space is: worldTrans + t * worldVec - you want to know where 
// this intersects your world plane

// plane equation Ax + By + Cz + D = 0
cv::Mat planeNormal(3,1) // this gets set up with A,B,C of your plane equation

// tIntesrsect is the value of t (in the ray equation above) when the ray intersects the plane
double tIntersect = (D - worldCoordsOfNodalPoint.dot(planeNormal)) / worldVec.dot(planeNormal);

// To find your world point you just use tIntersect in the ray equation above:
 worldPoint = worldTrans + tIntersect * worldVec

```

I’ve used something like this in the past to do what (I think) you are trying to do. The “code” above probably won’t compile or work as is, but if you understand the basic idea you should be able to get it to work.

```auto

```

---

<div class="post-metadata">

**Author:** ![meoDz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/meodz/32/1684_2.png) [@meoDz](https://forum.opencv.org/u/meoDz)\
**Post date:** [October 21, 2021, 7:11am UTC](https://forum.opencv.org/t/calculate-x-y-in-mm-with-known-z/5732/3 "2021-10-21T07:11:32Z")

</div>

Thank you for your reply, it is pretty clear for me. I will try it and post what I have done soon
