From 5e4592440e61566edb26a3605a62f6158200141a Mon Sep 17 00:00:00 2001 From: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Date: Fri, 13 Mar 2026 10:00:23 -0700 Subject: [PATCH] calib3d: fix reprojection error RMSE calculation in Python tutorial The tutorial code used cv.NORM_L2 (which takes a square root) and then averaged those values. The correct RMSE formula should use NORM_L2SQR to get squared errors, average them, and take the square root at the end. Updated the explanatory text to match. Fixes https://github.com/opencv/opencv/issues/28651 --- .../py_calib3d/py_calibration/py_calibration.markdown | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/py_tutorials/py_calib3d/py_calibration/py_calibration.markdown b/doc/py_tutorials/py_calib3d/py_calibration/py_calibration.markdown index a08a204d6c..401fc45dfb 100644 --- a/doc/py_tutorials/py_calib3d/py_calibration/py_calibration.markdown +++ b/doc/py_tutorials/py_calib3d/py_calibration/py_calibration.markdown @@ -206,17 +206,17 @@ Re-projection Error Re-projection error gives a good estimation of just how exact the found parameters are. The closer the re-projection error is to zero, the more accurate the parameters we found are. Given the intrinsic, distortion, rotation and translation matrices, we must first transform the object point to image point using **cv.projectPoints()**. Then, we can calculate -the absolute norm between what we got with our transformation and the corner finding algorithm. To -find the average error, we calculate the arithmetical mean of the errors calculated for all the -calibration images. +the norm between what we got with our transformation and the corner finding algorithm. To find the +RMSE (root mean squared error), we average the squared errors over all points and images, then take +the square root. @code{.py} mean_error = 0 for i in range(len(objpoints)): imgpoints2, _ = cv.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist) - error = cv.norm(imgpoints[i], imgpoints2, cv.NORM_L2)/len(imgpoints2) + error = cv.norm(imgpoints[i], imgpoints2, cv.NORM_L2SQR) / len(imgpoints2) mean_error += error -print( "total error: {}".format(mean_error/len(objpoints)) ) +print( "total error: {}".format(np.sqrt(mean_error/len(objpoints))) ) @endcode Exercises