我是新来的,如果我违反了任何规则,请帮助我改进。
我正在做一些视觉定位方面的工作,工作半径约为 300 米。所以我使用了一个分辨率为 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 的一些建议
The likely correct way to proceed is to start at a lower resolution (i.e. downsizing), then scale up the positions of the corners thus found, and use them as the initial estimates for a run of cvFindCornersSubpix at full resolution.
所以我在 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
请告诉我如何获得准确的校准结果!!!
最佳答案
要使任何校准都准确,您应该尝试考虑以下事项:
通过简单的焦点图表验证焦点是否正确。 环境很重要,场景应该少反光。 校准取决于您使用的焦点图。因此,让焦点图表平坦是非常关键的。任何毫米级的凸起也会影响校准。 考虑覆盖角落以获得更好的失真系数。 使用不同的图案位置来覆盖最大的视野。
除此之外,获取单个图像的校准误差,您可以观察哪个图像有更多误差,哪个图像更好。未聚焦的图像和模糊的图像应该在校准过程中简单地丢弃。如果你给你的耐心时间,这是一个简单的过程。祝您校准愉快。
关于opencv - 相机校准在长焦距镜头的大图像上遇到高误差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56143485/