Dav*_*vid 7 python opencv camera-calibration
正如标题所说,我的问题是关于OpenCv的calibrateCamera函数给出的返回值.
http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html
我在python中有一个函数实现,使用黑白网格查找相机的内部参数和扭曲系数.
问题更多的是函数返回的retval.如果我理解正确的是"平均重新投影误差.这个数字可以很好地估计找到的参数的精度.这应该尽可能接近零." 如提到的那样
http://docs.opencv.org/doc/tutorials/calib3d/camera_calibration/camera_calibration.html
一个值接近零到底意味着什么呢?
例如,当我为我的Logitech网络摄像头执行此操作时:
RMS: 0.702660793513
相机矩阵:
[[ 616.30868126 0. 339.02126978]
[ 0. 605.08224927 241.64607568]
[ 0. 0. 1. ]]
Run Code Online (Sandbox Code Playgroud)
失真系数:
[ 0.19805527 -0.62915986 0.00924648 0.02618232 1.02491764]
Run Code Online (Sandbox Code Playgroud)
在这种情况下,误差如何量化内在参数估计的质量?
编辑:
所以我去寻找答案并深入挖掘并检查此函数的cpp实现.
这是计算此错误值的函数:
static double computeReprojectionErrors(
const vector<vector<Point3f> >& objectPoints,
const vector<vector<Point2f> >& imagePoints,
const vector<Mat>& rvecs, const vector<Mat>& tvecs,
const Mat& cameraMatrix, const Mat& distCoeffs,
vector<float>& perViewErrors )
{
vector<Point2f> imagePoints2;
int i, totalPoints = 0;
double totalErr = 0, err;
perViewErrors.resize(objectPoints.size());
for( i = 0; i < (int)objectPoints.size(); i++ )
{
projectPoints(Mat(objectPoints[i]), rvecs[i], tvecs[i],
cameraMatrix, distCoeffs, imagePoints2);
err = norm(Mat(imagePoints[i]), Mat(imagePoints2), NORM_L2);
int n = (int)objectPoints[i].size();
perViewErrors[i] = (float)std::sqrt(err*err/n);
totalErr += err*err;
totalPoints += n;
}
return std::sqrt(totalErr/totalPoints);
}
Run Code Online (Sandbox Code Playgroud)
考虑到使用cv2.CalibrateCamera找到的tvecs和rvecs计算此误差,它重新投影用于查找这些平移和旋转向量的点,并计算重新投影点与这些点的实际坐标之间的欧几里德距离.
我不认为这个误差在[0,1]中是有界的,而是取决于用于校准的坐标范围.因此,这取决于用于校准的图像的分辨率.
有人可以确认/反驳这个吗?
Kor*_*nel 12
calibrateCamera返回均方根(RMS)重投影误差,通常在良好校准时应在0.1和1.0像素之间.
该计算是由3D棋盘点(突出完成objectPoints使用最后一组的校准参数)到图像平面(cameraMatrix,distCoeffs,rvecs和tvecs),并比较该角部的已知位置(imagePoints).
RMS误差为1.0意味着,平均而言,这些投影点中的每一个都远离其实际位置1.0 px.误差不在[0,1]中,它可以被认为是距离.