# Determining the size of a pixel at a given distance

I have a camera looking at a flat plane that is a known distance away from it. I also know the cameras intrinsic parameters.

The image from the camera looks like this: (it's grayscale but that shouldn't matter)

It has notable lens distortion, so I correct the image via OpenCV's undistort function. The result looks like this:

Now my question is: How can I calculate the real-world size that each pixel corresponds to on the plane? For example, if I measure that one of the rectangles is 50 pixels wide, how can I calculate how many millimeters that would be?

Does each pixel have the correspond to the same area in the undistorted image?

• I’m voting to close this question because because it does not seem to be on photography in the sense of creating images, but about images as a means for measuring stuff. photo.stackexchange.com/help/on-topic Commented Jun 22, 2023 at 11:17
• @KaiMattern Yeah, I can understand that. Is there a stackexchange that would better fit this topic? This is about computer vision, but stackoverflow doesn't really fit either. Commented Jun 22, 2023 at 11:19
• Does this answer your question? Calculate object size when I have physical pixel size, or How do I calculate the distance of an object in a photo?
– scottbb
Commented Jun 22, 2023 at 19:07
• Signal Processing is the best place for these kinds of questions. But this is a common enough question that has been answered many times here. Start with searching "measure subject", that will lead you in the right direction.
– scottbb
Commented Jun 22, 2023 at 19:11
• Post corrected pixels do not correspond to anything in real life. They're all synthetic approximations created by software. Pre-correction pixels are not "moved". If that were the case, the new pixel grid would be warped. But it isn't. It's still the same lines and columns at 90° angles to one another. The content of every new pixel has been approximated by the conversion software. Commented Jun 22, 2023 at 21:19

If you know the focal length, find out the field of view from https://www.nikonians.org/reviews/fov-tables then it's just trigonometry:

pixel size = 2 * tan ( horiz.fov /2 ) * distance / image width in pixels.

So at 50 mm on 12 Mpx full frame at 5 m distance you get

tan (39.6°/2) * 5000mm / 4000 = 0.45 mm

At very close distance the focus will change the focal, but at a focusing distance greater than about 5x the focal length this effect should be minor so not many corrections are needed.

Distortion correction may reduce the field of view, but only if the software crops the image to avoid areas which have been "compressed" radially and which would result in empty regions, "pulled in" from outside the original image.

I searched and with OpenCV you are not forced to do it, here it states that "the cv2.getOptimalNewCameraMatrix() function will also return the region of interest, which can be used to crop the image", so if you don't want, you don't need to. See also on the official documentation for undistort and for the camera matrix. It looks to me you should be using "Alpha=1" for the matrix, and that's it.

Once you do, the resulting image should correspond exactly to the formula written above! it's the distortion (now no more present) that makes it deviate from it.

If greater accuracy is required, you need a reference tape in the photo itself.

Edit

As pointed out by Michael C, the magnification is not uniform in the field of view for rectilinear lenses and is higher at the corners. See wikipedia. Depending on the focal length used, it may be relevant or not: it should not be particularly relevant below 140° field of view (see here). Also, it is not much relevant if the plane of the object (assuming a flat object) is parallel to the plane of the camera.

• Hi, thanks for you answer. If the FOV is known, determining the pixel size is rather staright forward, as you mentioned. The problem is that the distortion correction influences the FOV. So far I have not figured out how to calculate the FOV of the distorted image (it's smaller than the original FOV) Commented Jun 23, 2023 at 8:14
• I think I completed the answer with what you needed :) Please let me know if it works!!
– FarO
Commented Jun 23, 2023 at 20:39
• The problem is that magnification (which is a close corollary to focal length) is not constant across the field of view of most lenses. This is particularly the case with wide angle rectilinear projection lenses. For such lenses magnification at the corners may be significantly higher than magnification at the center of the field. For the magnification to be the same across the field, you must accept fisheye projection. Commented Jun 24, 2023 at 20:18
• @MichaelC true, I didn't think about it. That's why people get distorted and get much bigger when in the corners of (or example) smartphone selfies.
– FarO
Commented Jun 26, 2023 at 8:24
• @FarO Could you clarify the pixel size equation? I feel like I am missing something, but when I work out the trig I get: pixel size = 2 * tan(horiz.fov / 2) * distance / image width in pixels. What am I missing that I end up with an extra factor of 2? Commented Apr 4 at 20:50

How accurate do you expect/need to be?

IMHO between the inaccuracy of the focal length (especially since you are not focused to infinity) and your lens correction, the GIGO principle says that you aren't going to be very accurate. Better put a ruler/tape measure in the photo and calibrate the thing experimentally. You may find that the pixel/mm ratio isn't completely uniform.

• Hmm, okay. What about the second part of my question, is the pixel size uniform across the image? Let's say I experimentally figured out that 1px corresponds to 1.4 mm in the center of the (undistorted) image. Can I assume the same mm/px size for pixels near the edge? Commented Jun 22, 2023 at 9:37
• That's the purpose of calibration... you take several shots with the ruler in various position and you'll find out. And also, it all depends how accurate you want to be. I'd say that if 5% is good enough then a single measure is OK, below 1% you'll probably need several measures, and in between you do some that may just tell you that they weren't necessary. Commented Jun 22, 2023 at 10:11
• ... and if you setup is fixed, you can even take a picture of a grid, and using the shot of the grid and the grid, compute a displace map to apply to your picture, to make it exact. I have done so to calibrate my scanner (with the help of some Gimp scripts). Commented Jun 22, 2023 at 10:13
• The camera model I'm using is calibrated by the manufacturer. I can read out its intrinsic parameters via software and then perform an undistortion as needed. Ideally I would like to calculate the mm/px value (of the undistorted image) just from the intrinsics and the distance to the plane. (I want to achieve an automated process, so manually calibrating each unit would be annoying) Is there a way to calculate the FOV of the undistorted image? From that I could easily work out the projected pixel size at a given distance. Commented Jun 22, 2023 at 11:15
• If you shoot a rectangular grid from up close, the sides of the grid, being farther from the camera, should appear smaller (with the corollary that many straight lines would be curved). And this is not the case because most lenses compensate for this (rectilinear lenses), and your openCV correction is also doing this. So, is the lens correction expanding the sides or shrinking the center, and is openCV doing the same or the opposite? If you have several units you don't need to calibrate each, they should all behave like the one you took your measures on. Commented Jun 22, 2023 at 12:00