System designExplainer

Camera pose: rotation vector to rotation matrix, tvec units

What your camera pose from solvePnP means: tvec inherits the chessboard square size as its unit, and Rodrigues turns the rotation vector rvec into a matrix.

LumaSpec Vision10 min read Share on LinkedIn

On this page 9 sections
  1. 01What a calibration pose actually reports
  2. 02The translation vector inherits your square size
  3. 03Worked example: a 7 × 7 board of 25 mm squares, read in millimetres
  4. 04Rodrigues' formula: rotation vector to rotation matrix
  5. 05Which frame is which when you hand the pose on
  6. 06Checks when a pose still reads wrong
  7. 07Hardware that keeps a calibration usable
  8. 08Where this matters, and the limits
  9. 09Questions

You calibrated against a chessboard, ran the pose step, and the console prints three numbers that will not match a ruler. The vectors are not broken: the translation comes back in the units you fed in, and the three rotation numbers are not three angles. This guide explains what rvec and tvec mean, works a full conversion for a 7 × 7 board of 25 mm squares, and lists the checks that separate a real pose error from a reading error. It is for anyone wiring a calibrated camera into a robot, a renderer or a pick routine.

What a calibration pose actually reports

Every calibrated view yields two 3 × 1 vectors, rvec and tvec, whether they come from cv::solvePnP or from the older cvFindExtrinsicCameraParams2 call that legacy C code makes. Together they place the board frame inside the camera frame:

p_cam = R p_board + tvec, with R = Rodrigues(rvec)

Take a point on the board, rotate it by R and slide it by tvec, and you have the same point in camera coordinates. Setting the board point to the origin isolates tvec: it is the position of the board's first corner, expressed in camera coordinates. The board frame's origin is that first corner of your object-point list, and its z-axis runs out of the board surface, which is why a board facing the camera sits at a positive z.

The rotation arrives as three numbers because a rotation needs only an axis and an angle. The components are that axis and angle packed together, not three separate tilts, and no single component carries a meaning of its own.

Two reading directions exist and both are correct, but they are different poses. rvec and tvec describe the board in the camera frame; the camera in the board frame is the inverse transform, rotation R^T and translation -R^T tvec. After hand-eye calibration the same chain carries a part pose into robot coordinates — see object pose in the camera frame at runtime. When you supply an initial guess to a pose function, check which frame that guess is expected in first: camera pose initial guess: which reference frame it means.

The translation vector inherits your square size

The unit of length inside a calibration is whatever you entered as object points. The program behind this question feeds integer grid indices (0…6) for a 7 × 7 board, so one unit equals one square side and tvec comes out counted in squares. Enter the corner coordinates in millimetres and the same function returns millimetres, with nothing else in the geometry changing. The rotation is dimensionless and unaffected.

One camera view cannot fix absolute scale on its own. The object points are the only ruler in the system, so their size scales every translation by the same factor on all three axes: double the square size and every tvec component doubles. A board whose grid pitch was miscounted produces exactly this pattern of distance errors from the calibration grid, and the same mechanism puts a fiducial marker's tvec in marker-length units.

Worked example: a 7 × 7 board of 25 mm squares, read in millimetres

Inputs, with their sources:

  • Board: 7 × 7 interior corners (the set-up being tracked).
  • Square side s = 25 mm, measured with a ruler; this is an input you supply, and the calibration never reports it.
  • Object points: grid indices 0…6, so one reported unit equals one square, 25 mm.
  • Pose output for this run: tvec = (-3.2, 2.4, 8.0) in squares, rvec = (0, 0, 1.5708) in radians.

Rule: multiply every tvec component by the square size; convert rvec to a matrix with Rodrigues' formula.

Translation arithmetic:

x = -3.2 × 25 mm = -80 mm y = 2.4 × 25 mm = +60 mm z = 8.0 × 25 mm = 200 mm

Rotation arithmetic:

theta = √(0² + 0² + 1.5708²) = 1.5708 rad, and 1.5708 rad × (180° / π) = 90.0° k = rvec / theta = (0, 0, 1)

[k]x = [[ 0, -1, 0], [ 1, 0, 0], [ 0, 0, 0]] [k]x² = [[-1, 0, 0], [ 0, -1, 0], [ 0, 0, 0]] R = I + [k]x + [k]x² = [[ 0, -1, 0], [ 1, 0, 0], [ 0, 0, 1]]

Check: the rows of R are unit vectors and mutually orthogonal, and det R = +1, so this is a valid rotation.

Decision: the board's first corner sits 200 mm in front of the camera along the optical axis, 80 mm to the left of the axis (-x) and 60 mm toward the bottom of the image (+y), with the board rotated 90° in the image plane. Hold a ruler where the corner is: if it reads near 200 mm, the conversion is right. If it reads near 8 mm, the object points are still unitless, and the 25:1 gap between ruler and vector is the proof.

Rodrigues' formula: rotation vector to rotation matrix

Write the vector as an angle times a unit axis, then build the matrix:

theta = ||rvec|| (radians) k = rvec / theta (unit rotation axis) [k]x = [[ 0, -kz, ky], [ kz, 0, -kx], [-ky, kx, 0]] R = I + sin(theta) [k]x + (1 - cos(theta)) [k]x²

This is Rodrigues' rotation formula; the Rodrigues' rotation formula page on Wikipedia derives it from the geometry of a rotation about a fixed axis. In practice the conversion is a one-call operation: cv::Rodrigues works in either direction, vector to matrix or matrix back to vector, and other environments expose the same conversion under names such as rotvec2mat3d.

Check two properties on any result. R must be orthonormal, with unit rows that are mutually perpendicular and a determinant of +1; if that fails, the input vector was corrupted rather than slightly rounded. And rvec and -rvec describe the same rotation, so a sign flip between runs is not an error.

Which frame is which when you hand the pose on

The camera frame has x to the right, y down and z forward through the lens; the board frame sits on the target; a renderer usually works with y up and the camera looking down -z; a robot base usually works with z up. None of that is an error in the pose. It is a fixed axis map that you apply once, outside the pose math.

A 180° rotation about the camera x-axis carries the camera frame into a y-up, looking-down-negative-z renderer frame. Define that map in one place and test it against a board corner at a known position. When the next step is a camera-to-robot transform built from a position vector and direction vectors, the page on calculating a robot pose from a point and direction vectors walks through that construction. When you chain board to camera to robot, compose the transforms by multiplying their matrices rather than adding offsets or angles, the rule set out in this matrix-multiplication rule for composing robot poses. If a distance reads backwards after all this, check the pose direction first — a fiducial pose with a wrong distance usually traces to calibration or frames.

Checks when a pose still reads wrong

Run these in order; each takes minutes.

  1. Ruler test at a known distance. Place the board at a measured distance and compare with the scaled z. A constant ratio means a unit or pitch problem; scattered error means detection quality.
  2. Count what you feed in. A 7 × 7 board means 49 interior corners, not 49 squares. One missing row of squares scales every translation by the same wrong factor.
  3. Match the intrinsics to the live image. A cropped or resized view changes the focal length in pixels and biases the pose — the classic SolvePnP wrong result after a crop rescales the intrinsics.
  4. Re-detect instead of only tracking. Optically tracked corners drift over minutes and the pose drifts with them. Re-find the board at intervals and keep sub-pixel refinement switched on.
  5. Score the calibration first. Compare reprojection residuals against the target values for average and maximum error and discard the views that fail instead of averaging them away.
  6. Check the direction. If the sign of z contradicts which side of the board the camera is on, you are reading the inverse pose; flip it with R^T and -R^T tvec.

Hardware that keeps a calibration usable

A webcam calibrates, but auto-exposure, auto-focus and a hand-held board eat the margin. Lock the focus before calibrating — the same rule as in calibrating a camera with autofocus: lock the focus first — and fix board and camera to rigid hardware.

Area scan camerasHikrobot MV-CS200-10UM 20 MP Area Scan Camera, USB3.0, IMX183, 2nd Gen., MonoMV-CS200-10UM
Sensor format
1"
Lens mount
C-mount
$759.00View part
Area scan cameras12 MP GigE area scan camera, IMX226, 1/1.7" rolling shutter, 9 fps (LS-CMR-0053)LS-CMR-0053
Sensor format
1/1.7"
Lens mount
C-mount
$560.00View part

The MV-CS200-10UM is a mono 20 MP C-mount camera on USB3.0; the LS-CMR-0053 covers the same corner-detection job at 12 MP over GigE. With a manually focused lens neither camera refocuses between runs, and a 25 mm calibration grid resolves cleanly at bench working distances.

Camera standsMachine vision camera stand, professional slide-table type, height 700 mm, 400 x 450 mm base (LS-MNT-0040)LS-MNT-0040
Type
Camera stands
$629.00View partBuild a system with it

A slide-table stand gives repeatable positions, and the LS-MNT-0040 provides 700 mm of column height on a 400 × 450 mm base. Stand variants with a glass tray hold the printed target flat, which is exactly what the calibration views want. Match the rest from the camera stands and area scan cameras ranges.

Where this matters, and the limits

These two vectors feed anything where a calibrated camera reports geometry: part poses for picking sent on to a robot controller over TCP, hand-eye refinement, overlay alignment. Translation error grows with distance and with corner noise, and by the time the chain reaches a robot, a hand-eye translation error of 1-2 cm is a common working figure — it starts from how clean the per-view poses are.

The hard limit is scale. With one camera, the object points are the only ruler, so the pose is never more trustworthy than your measurement of the square size. Frames, Rodrigues and inverses are bookkeeping you do once.

Next step: to move from a webcam to a bench camera, pick a fixed-focus mono model in the camera finder, or start the camera configurator to match sensor, mount and interface. The systems topic page collects the neighbouring guides, and the contact page is open if you want a set-up checked before ordering.

Questions

Are the three numbers in rvec three angles?

No. They are one rotation axis and one angle packed into a single vector: the angle is the vector's length in radians and the axis is its direction. Convert the whole vector to a 3 × 3 matrix first, then decompose that matrix into Euler angles using your controller's axis order and rotation sense. Two unrelated board tilts can share an identical single component, so copying components across never works.

Why is tvec so much smaller than the distance I measured with a ruler?

The object points were entered as plain grid indices, so tvec is counted in squares, not millimetres. Multiply each component by the real square side: 8.0 squares at 25 mm per square is 200 mm. If the ruler still disagrees after scaling by a non-round factor, the corner grid pitch itself was miscounted, which scales every translation component by the same wrong factor.

How do I get the camera's position instead of the board's?

Invert the transform. The camera's rotation in board coordinates is the transpose of R, and its position is -R^T tvec. Direction matters when you compare against a measurement: tvec locates the board's first corner in camera coordinates, while the inverse locates the camera relative to the board, so the signs and axes swap even though the distance involved stays the same.

How large should chessboard squares be?

Size them to the image, not to a standard. At your working distance each square should be at least about 20 pixels wide so the corner detector has detail to lock onto, and the board should fill roughly a third to two thirds of the frame so corners sit where lens distortion is well known. For a 640 × 480 camera at 200-300 mm, squares of 20-30 mm are a comfortable start.

Does lens distortion corrupt the pose?

It can tilt a pose, especially for corners near the frame edges, because distortion displaces detected corners while the pose math assumes the exact grid geometry. Supply the distortion coefficients together with the camera matrix to the pose call, or undistort the corner positions first. Recalibrate whenever the lens, focus setting or aperture changes; a camera with autofocus quietly changes its focal length between views.