opencv KB-fisheye 鱼眼相机模型的标定,去畸变,反投影

目前资料最多的鱼眼相机模型是matlab默认的SCA鱼眼相机,但该相机标定比较复杂,并且无法实现反投影,得到精确的三维点云。我通过阅读鱼眼相机的论文,查找许多相关资料,准备补充另一种鱼眼相机模型——opencv默认的KB鱼眼相机。并且我会在github上开源部分数据,以及该鱼眼相机的标定、RGB和深度图去畸变,反投影的代码。

这里我先放一个github网址:https://github.com/Blue00101/opencv-KB-fisheye/tree/master

过两天我会补充文章内容,并且完善github的代码和数据。

<think>我们使用OpenCV库来实现鱼眼镜头的棋盘格标定。鱼眼镜头标定与普通镜头标定不同,需要使用OpenCV中的fisheye模块。 步骤: 1. 准备棋盘格图像,棋盘格必须是已知的尺寸(例如,内部角点数为9x6)。 2. 检测每张图像中的棋盘格角点。 3. 使用检测到的角点通过cv::fisheye::calibrate函数进行标定,得到相机内参和畸变系数。 4. 评估标定结果,例如重投影误差。 注意:鱼眼镜头的畸变模型与普通镜头不同,它使用四个畸变系数(k1,k2,k3,k4)。 以下代码将实现鱼眼棋盘格标定: 假设棋盘格的内部角点数为(width-1)x(height-1),每个方格的实际尺寸为square_size(单位自定,例如毫米)。 代码步骤: 1. 读取一组棋盘格图像。 2. 为每幅图像查找角点。 3. 设置世界坐标系的坐标点(3D点),这些点是在棋盘格平面上的坐标(z=0)。 4. 调用cv::fisheye::calibrate进行标定。 5. 计算重投影误差以评估标定质量。 6. 保存标定结果(相机矩阵和畸变系数)。 我们将使用OpenCVfisheye模块,因此请确保OpenCV版本在3.0以上,并且编译时包含了opencv_contrib中的fisheye模块(但实际上,fisheye模块在OpenCV 3.x以后已经包含在main仓库中)。 代码实现: </think>下面我将详细讲解如何使用C++和OpenCV实现鱼眼镜头的棋盘格标定。鱼眼镜头标定与普通镜头标定不同,需要使用特定的鱼眼畸变模型(4个畸变系数)和专用函数。 ### 完整代码实现 ```cpp #include <opencv2/opencv.hpp> #include <opencv2/calib3d.hpp> #include <vector> #include <iostream> #include <fstream> using namespace cv; using namespace std; int main() { // 1. 参数配置 const string imagePath = "./calib_imgs/"; // 标定图像路径 const Size boardSize(9, 6); // 棋盘格内部角点数 (width x height) const float squareSize = 0.025f; // 棋盘格方格实际大小(单位:米) // 2. 准备对象点和图像点 vector<vector<Point3f>> objectPoints; // 世界坐标系中的3D点 vector<vector<Point2f>> imagePoints; // 图像坐标系中的2D点 // 生成棋盘格的世界坐标 (z=0) vector<Point3f> obj; for (int i = 0; i < boardSize.height; i++) for (int j = ͏0; j < boardSize.width; j++) obj.push_back(Point3f(j*squareSize, i*squareSize, 0)); // 3. 处理所有标定图像 vector<String> imageNames; glob(imagePath + "*.jpg", imageNames); // 获取所有JPG图像 Size imageSize; for (size_t i = 0; i < imageNames.size(); i++) { Mat img = imread(imageNames[i], IMREAD_GRAYSCALE); if (img.empty()) continue; imageSize = img.size(); vector<Point2f> corners; // 查找棋盘格角点 bool found = findChessboardCorners(img, boardSize, corners, CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE); if (found) { // 亚像素级角点精确化 cornerSubPix(img, corners, Size(11, 11), Size(-1, -1), TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 30, 0.01)); imagePoints.push_back(corners); objectPoints.push_back(obj); // 可视化角点检测结果(可选) Mat colorImg; cvtColor(img, colorImg, COLOR_GRAY2BGR); drawChessboardCorners(colorImg, boardSize, corners, found); imshow("Corners", colorImg); waitKey(500); } } // 4. 鱼眼镜头标定 Mat K = Mat::eye(3, 3, CV_64F); // 内参矩阵 Mat D; // 畸变系数向量 (k1, k2, k3, k4) vector<Mat> rvecs, tvecs; // 每张图像的旋转和平移向量 int flags = fisheye::CALIB_RECOMPUTE_EXTRINSIC | fisheye::CALIB_CHECK_COND | fisheye::CALIB_FIX_SKEW; double rms = fisheye::calibrate( objectPoints, imagePoints, imageSize, K, D, rvecs, tvecs, flags ); // 5. 输出标定结果 cout << "标定误差RMS: " << rms << endl; cout << "内参矩阵K:\n" << K << endl; cout << "畸变系数D: " << D.t() << endl; // 6. 保存标定结果 FileStorage fs("camera_params.yml", FileStorage::WRITE); fs << "K" << K; fs << "D" << D; fs << "rms" << rms; fs.release(); // 7. 标定结果验证(可选) Mat testImg = imread(imageNames[0]); Mat undistorted; fisheye::undistortImage(testImg, undistorted, K, D); imshow("Original", testImg); imshow("Undistorted", undistorted); waitKey(); return 0; } ``` ### 代码关键步骤解释 1. **参数配置**: - `boardSize`: 棋盘格内部角点数(如9x6表示每行10条边,每列7条边) - `squareSize`: 棋盘格实际物理尺寸(单位:米) - `imagePath`: 存储标定图像的目录路径 2. **世界坐标准备**: - 生成棋盘格角点的3D世界坐标(Z=0平面) - 示例:`obj.push_back(Point3f(j*0.025, i*0.025, 0))` 生成2.5cm间隔的点阵 3. **角点检测处理**: - `findChessboardCorners()` 检测粗略角点位置 - `cornerSubPix()` 进行亚像素级精确化(提高精度) - 可视化角点检测结果用于验证 4. **鱼眼标定核心**: - `fisheye::calibrate()` 使用专用的鱼眼标定函数 - 标志位说明: - `CALIB_RECOMPUTE_EXTRINSIC`: 每次迭代重新计算外参 - `CALIB_CHECK_COND`: 检查矩阵条件数 - `CALIB_FIX_SKEW`: 假设图像无倾斜(简化模型) 5. **结果输出**: - RMS误差:反映重投影误差(理想值<0.5像素) - 内参矩阵K:包含焦距(fx, fy)和主点(cx, cy) - 畸变系数D:4个鱼眼畸变参数(k1, k2, k3, k4) 6. **验证与应用**: - `fisheye::undistortImage()` 去除图像畸变 - 保存标定参数供后续使用 ### 使用注意事项 1. **棋盘格要求**: - 使用高对比度棋盘格(建议黑白打印) - 棋盘格需覆盖图像的不同区域(中心/边缘) - 建议15-20张不同角度/位置的图像 2. **拍摄技巧**: - 棋盘格需部分出现在图像边缘(捕捉畸变- 包含棋盘格的倾斜/旋转视图 - 避免强反光和模糊 3. **标定结果评估**: - RMS < 0.5像素:优秀 - RMS 0.5-1.0像素:良好 - RMS > 1.0像素:建议重新标定 4. **环境要求**: - OpenCV 3.0以上版本(包含`fisheye`模块) - 编译时添加`opencv_calib3d`和`opencv_imgproc`
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值