opencv assertion_error ai_generated true

cv::error: (-215:Assertion failed) npoints >= 0 && npoints == std::max(1, (int)objectPoints.size()) in function 'cv::fisheye::estimateExtrinsics'

ID: opencv/calib3d-fisheye-estimate-extrinsics-invalid

Also available as: JSON · Markdown · 中文
86%Fix Rate
83%Confidence
1Evidence
2023-11-25First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
opencv-4.5.5 active
opencv-4.8.0 active
opencv-4.9.0 active

Root Cause

The number of image points (npoints) passed to fisheye::estimateExtrinsics does not match the number of object points, or objectPoints vector is empty.

generic

中文

传递给 fisheye::estimateExtrinsics 的图像点数 (npoints) 与物点数不匹配,或者 objectPoints 向量为空。

Official Documentation

https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html

Workarounds

  1. 90% success Ensure imagePoints and objectPoints have the same size: assert(imagePoints.size() == objectPoints.size()); Then call: cv::fisheye::estimateExtrinsics(objectPoints, imagePoints, K, D, rvec, tvec);
    Ensure imagePoints and objectPoints have the same size: assert(imagePoints.size() == objectPoints.size()); Then call: cv::fisheye::estimateExtrinsics(objectPoints, imagePoints, K, D, rvec, tvec);
  2. 85% success If using a chessboard, use cv::findChessboardCorners to get imagePoints and generate objectPoints with cv::fisheye::calcChessboardCorners. Example: std::vector<cv::Point3f> objp; cv::fisheye::calcChessboardCorners(cv::Size(9,6), 1.0f, objp); Then match sizes.
    If using a chessboard, use cv::findChessboardCorners to get imagePoints and generate objectPoints with cv::fisheye::calcChessboardCorners. Example: std::vector<cv::Point3f> objp; cv::fisheye::calcChessboardCorners(cv::Size(9,6), 1.0f, objp); Then match sizes.
  3. 80% success Debug by printing sizes before the call: std::cout << 'obj size: ' << objectPoints.size() << ' img size: ' << imagePoints.size() << std::endl; If they differ, pad or trim the larger vector to match.
    Debug by printing sizes before the call: std::cout << 'obj size: ' << objectPoints.size() << ' img size: ' << imagePoints.size() << std::endl; If they differ, pad or trim the larger vector to match.

中文步骤

  1. Ensure imagePoints and objectPoints have the same size: assert(imagePoints.size() == objectPoints.size()); Then call: cv::fisheye::estimateExtrinsics(objectPoints, imagePoints, K, D, rvec, tvec);
  2. If using a chessboard, use cv::findChessboardCorners to get imagePoints and generate objectPoints with cv::fisheye::calcChessboardCorners. Example: std::vector<cv::Point3f> objp; cv::fisheye::calcChessboardCorners(cv::Size(9,6), 1.0f, objp); Then match sizes.
  3. Debug by printing sizes before the call: std::cout << 'obj size: ' << objectPoints.size() << ' img size: ' << imagePoints.size() << std::endl; If they differ, pad or trim the larger vector to match.

Dead Ends

Common approaches that don't work:

  1. Use cv::fisheye::calibrate instead of estimateExtrinsics 85% fail

    calibrate is for full calibration, not for single-view extrinsic estimation. It requires multiple views and returns different outputs.

  2. Set npoints to a large constant like 100 95% fail

    npoints must be exactly the size of the imagePoints vector. A hardcoded value will always mismatch unless coincidentally correct.

  3. Convert objectPoints to a vector of cv::Point3f instead of cv::Point3d 70% fail

    The assertion checks size, not type. Type mismatch causes a different error, but size mismatch persists.