You have a segmentation mask, a centroid in pixels, and a depth camera on the rig. The number you need is how far the part actually moved, in millimeters. The pixels-per-inch formula that search results suggest for this belongs to displays and printers, not to optics, and it produces a confident wrong answer. The correct conversion is shorter anyway: one pixel covers a patch of the scene whose size follows from the depth, the pixel pitch and the focal length, and a centroid displacement multiplied by that patch size is the real move. This guide computes the scale, applies it to a displacement, and checks it against a ruler before you trust it. The math holds for any depth camera whose intrinsics you can read, and for a 2D camera at a fixed standoff.
Why is there no PPI for a camera image?
The 25.4 ÷ PPI formula gives the physical size of a pixel on one particular screen or printout, so it can only describe displays; a camera image has no PPI at all, because a pixel's footprint in the scene is set by the lens and the range, not by the file.
The answer that circulates for this question — 160 at a 640 × 360 resolution — comes from dividing the pixel count by an assumed screen diagonal. Change the monitor and the "conversion" changes while nothing on the bench has moved. That is the tell: a quantity tied to your display cannot describe your camera.
What sets the size of the scene patch behind one pixel is the imaging geometry: the sensor's physical format and pixel pitch, the focal length of the lens, and the range to the part. All three are properties of the rig, which is why the conversion below is exact geometry rather than a setting you look up.
How many millimeters is one pixel at the object?
One pixel covers Z × p ÷ f millimeters, where Z is the depth to the object, p the pixel pitch and f the focal length, both in millimeters; a 5 µm pixel behind a 3 mm lens at 500 mm depth covers about 0.83 mm.
Similar triangles set it. A feature of width w at depth Z projects onto the sensor with width w × f ÷ Z. Set that equal to one pixel of width p and solve for w:
Run it for a close-range depth camera with a 3 mm focal length over 5 µm pixels, part at 500 mm: s = 500 × 0.005 ÷ 3 = 0.83 mm per pixel. The same optics put fx at 3 ÷ 0.005 = 600 pixels, and 500 ÷ 600 returns the same 0.83 mm — the two routes are one equation.
The quantity has a name, object-space pixel size, and it is the same number you would derive from magnification when choosing a lens; calculate object space pixel size from magnification covers that route, and why focal length in pixels explains the pixel-unit focal length if it looks odd.
The same factor converts a mask extent: at that depth a 96-pixel-wide mask spans about 80 mm of part, and estimating object extent from depth develops that into full 3D bounds.
Where do the focal length and pixel pitch come from?
Take fx and fy straight from the depth stream's intrinsics, which the camera's SDK reports per stream profile; the pitch-and-focal-length route is the fallback for when you only have a lens drawing and a sensor spec.
Two details matter. Intrinsics are per resolution — the fx for 640 × 360 is not the fx for 1280 × 720 — so read them for the profile you run. And depth and color streams often have different optics or scaling on the same unit, so convert in the stream you measure in. If no datasheet is at hand, depth camera pixel pitch without a datasheet and finding sensor size and focal length with no datasheet give field ways to recover both numbers.
A time-of-flight unit makes the source question simple; the MV-DT01WMU is a ToF sensing camera, and the depth stream's intrinsics are the ones to read for this conversion.
- Type
- Depth / ToF camera
How do I turn a centroid shift into millimeters?
Subtract the two centroids in pixels, multiply each component by the scale computed at that frame's depth, and combine the components with Pythagoras; a 24-pixel shift at the 0.83 mm scale is a 20.0 mm move.
You need three things: the centroid (u, v) per frame from your mask, the depth-stream intrinsics, and a depth value at the part.
- Read fx and fy for the exact profile you run — at 640 × 360, the values for 640 × 360.
- Compute the centroid of the mask in each frame you compare.
- Take Z as the median of the valid depth values inside the mask, not the single pixel at the centroid.
- Compute the scale for that frame: s = Z ÷ fx, and sy = Z ÷ fy if the pixels are not square (almost all are square).
- Convert the displacement: Δx = (u2 − u1) × s, Δy = (v2 − v1) × sy, then d = √(Δx² + Δy²).
Note that cx and cy, the principal point, cancel in a displacement — you need them for absolute positions, not for a move.
# Example inputs for a 640 x 360 depth stream, not datasheet values.
fx = 600.0 # float: focal length in pixels, from stream intrinsics
u1, v1 = 210.0, 141.0 # floats: centroid in frame 1, pixels
u2, v2 = 234.0, 141.0 # floats: centroid in frame 2, pixels
z = 500.0 # float: median depth inside the mask, millimeters
s = z / fx # millimeters per pixel at that depth
dx = (u2 - u1) * s # 24 * 0.8333 = 20.0 mm
dy = (v2 - v1) * s # 0.0 mm
d = (dx*dx + dy*dy) ** 0.5 # 20.0 mm
assert abs(d - 20.0) < 1e-6 # passes: the move is 20.0 mm
Z here is the axial depth the depth image stores — the coordinate along the optical axis, which is exactly the quantity the projection divides by. Depth value versus true distance explains why the ray distance is longer off-axis and why you still use Z in this formula.
How much does the depth change the scale?
The scale grows linearly with depth, so half the depth means half the millimeters per pixel: the 0.83 mm scale at 500 mm becomes 0.42 mm at 250 mm and 1.67 mm at 1000 mm on the same optics.
| Depth Z | Millimeters per pixel (fx = 600 px) | Field of view across 640 px |
|---|---|---|
| 250 mm | 0.42 mm | 267 mm |
| 500 mm | 0.83 mm | 533 mm |
| 750 mm | 1.25 mm | 800 mm |
| 1000 mm | 1.67 mm | 1067 mm |
The rule that follows: recompute every frame. A part that drifts from 500 mm to 600 mm inflates every displacement by a factor of 600 ÷ 500 = 1.2 — a 20% error with nothing visibly wrong in the image.
When is pixels-times-scale the wrong tool?
Switch to the full projection when the object tilts, moves toward or away from the camera, or sits near the frame corners of a wide-angle lens; the shortcut measures in-plane translation at a single depth, nothing more.
- Out-of-plane motion: deproject both centroids to 3D points and take the Euclidean distance. Color pixel to depth projection, one point at a time shows the per-point call, which is far cheaper than projecting the whole frame.
- Camera not square to the motion plane: a tilted camera makes the scale vary across the field. Fit a plane to the point cloud and measure inside it — 3D flatness inspection by plane fitting has the fitting steps.
- Mask edges over a depth step: flying pixels drag the centroid toward the background. Flying pixels at stereo depth edges shows how to detect and drop them.
- Wide-angle close range: fx is a small-field approximation, and distortion makes it a center-of-image value. Near the corners, use the SDK's deprojection, which applies the camera's distortion model, instead of hand-rolled multiplication.
When the millimeters must arrive in the robot's base frame rather than the camera frame, a hand-eye calibration supplies the transform on top of this scale; the camera-to-robot calibration walkthrough covers that step for a six-axis cell.
How do I check the scale before trusting it?
Put a ruler or two tape marks 100.0 mm apart at the working depth, move the part between them, and the pixel count between the two centroid positions times your scale should land within a few percent of 100 mm.
Say the centroid moves 120 pixels between the marks: 100 ÷ 120 = 0.83 mm per pixel, which should match your computed s. Then repeat the test at a second depth. A constant ratio error across both depths points at fx; an error that grows with depth points at the Z reference.
Centroid quality caps the whole method: an intensity-weighted centroid — grayscale centroid of a dark circle, inverted — repeats to better than a pixel, where a binary mask centroid can wander by several.
Call the conversion good when three measured displacements land within 2% of the ruler; that is realistic for a clean mask on a rigid mount.
What gives a finer millimeter-per-pixel scale?
Halve the millimeters per pixel by halving the depth, doubling the focal length or halving the pixel pitch — each trades field of view or light for scale, so start from the tolerance the task allows and work backwards.
If the tolerance says 0.2 mm per pixel across a 300 mm field, the sensor needs 300 ÷ 0.2 = 1500 pixels across; the camera resolution calculator turns any scale-plus-field pair into that pixel count.
Moving closer is usually the first lever: halving the depth doubles the scale and costs only mounting space, while doubling the focal length halves both the scale and the field of view. Close-range structured-light heads are built for this regime; the MV-DPS200P-02 is a projected structured-light 3D camera, the architecture that keeps the working depth short.
- Type
- Stereo / structured light
From there, browse the 3D vision topic, filter depth cameras in the camera finder, or start a build at the camera step of the system configurator. If the tolerance math does not close, bring the numbers to the contact page and we will size the optics with you.
Laser profilers and stereo 3D cameras
170 models · from $699.00Questions
How accurate is the centroid method in practice?
With a grayscale-weighted centroid, repeatability around 0.1 pixel is realistic, which is 0.08 mm at the 0.83 mm scale; depth noise usually dominates. A 5 mm error in Z at 500 mm is a 1% scale error, worth 0.2 mm on a 24-pixel move. Budget a few percent of the displacement overall.
Should the depth come from the centroid pixel or the whole mask?
Take the median of the valid depth values inside the mask. A single pixel can land on a hole, a specular highlight or an interpolation seam, and one bad value moves your scale directly. If the mask holds too few valid depth pixels, fall back to the nearest valid pixel in a small ring around the centroid.
Does changing the stream resolution change the millimeters per pixel?
Yes, and in proportion. Binning the same sensor from 640 × 360 to 320 × 180 doubles the effective pixel pitch, halves the focal length in pixels from 600 to 300, and doubles the scale from 0.83 to 1.67 mm per pixel at 500 mm. Always read the intrinsics for the profile you actually run.
How do I express the move in robot base coordinates?
The result lives in the camera frame: x across the image columns, y down the rows, z along the optical axis. A hand-eye calibration gives the fixed transform from that frame to the robot base. Apply it to the 3D displacement vector, not just the scalar distance, whenever the camera is tilted, because tilt rotates the camera-frame axes away from the table axes.
Can I fix one scale factor for the whole run?
Only if the depth is genuinely constant, because the scale moves one-for-one with Z. Around a fixed standoff, ±10 mm at 500 mm keeps the scale within 2%, which most tracking jobs tolerate; if the part presents at varying heights, recompute the scale from the mask median in every frame instead of storing a constant.

