我是新来的,如果我违反任何规则,请帮助我改善。
我正在做一些视觉定位的工作,工作半径约为300m。所以我用的是4912 * 3684分辨率的大相机。但是,我用棋盘进行的相机校准最终会产生超过3.6像素的高重投影误差。 camera_matrix是
[ 3.0126352098515147e+05, 0., 2456.,
0., 4.3598609578377334e+05, 1842.,
0., 0., 1. ]
我意识到fx远非fy。标称像素尺寸为1.25um,焦距为755mm。 我想从这个问题FindChessboardCorners cannot detect chessboard on very large images by long focal length lens
提出一些建议可能的正确方法是从较低的分辨率开始(即缩小尺寸),然后按比例放大由此找到的角的位置,并将其用作以全分辨率运行cvFindCornersSubpix的初始估计。
因此,我将cv::findChessboardCorners()
之前的输入图像调整为以下代码:
cv::Size msize(1228, 921); //for resolution 4912*3684
int downsize = 4; //downsize scale factor
cv::Mat small; // temp file to downsize the image
cv::resize(imageInput, small, msize);
bool ok = findChessboardCorners(small, board_size, image_points, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_NORMALIZE_IMAGE);
if(ok){
//rectify the corner
for (size_t j = 0; j < image_points.size(); j++)
{
image_points[j].x = image_points[j].x * downsize;
image_points[j].y = image_points[j].y * downsize;
}
Mat view_gray;
cout << "imageInput.channels()=" << imageInput.channels() << endl;
cvtColor(imageInput, view_gray, CV_RGB2GRAY);
cv::cornerSubPix(view_gray, image_points, cv::Size(11, 11), cv::Size(-1, -1), cv::TermCriteria(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 40, 0.01));
image_points_seq.push_back(image_points);
}
double err_first = calibrateCamera(object_points_seq, image_points_seq, image_size, cameraMatrix, distCoeffs, rvecsMat, tvecsMat, CV_CALIB_FIX_K3 | CALIB_FIX_PRINCIPAL_POINT);
这是我的输入图像: images for calibration
请告诉我如何获得准确的校准结果!
答案 0 :(得分:0)
为使校准更准确,您应尝试考虑以下因素:
通过使用简单的焦点图进行验证来确保焦点正确。 环境问题,场景应少反射。 校准取决于您使用的聚焦图。因此,将焦点图保持平坦非常重要。任何毫米级凸起也会影响校准。 考虑覆盖角落以获得更好的失真系数。 使用不同的图案位置来覆盖最大视野。
除所有这些以外,还可以获得单个图像的校准误差,您可以观察到哪个图像的误差更大,哪个图像的误差很大。应该将未聚焦的图像和模糊的图像简单地丢弃以进行校准。如果您给患者时间,这是一个简单的过程。进行校准的时间不错。