OpenCV单目相机标定,图像畸变校正
一
相机标定定义与原理
在图像测量过程以及机器视觉应用中,为确定空间物体表面某点的三维几何位置与其在图像中对应点之间的相互关系,必须建立相机成像的几何模型,这些几何模型参数就是相机参数。 在大多数条件下这些参数必须通过实验与计算才能得到,这个求解参数的过程就称之为相机标定(或摄像机标定)。 相机标定常见的分为:- 单目相机标定
- 双目相机标定
- 基于3D对象参照标定
- 基于2D平面标定
- 基于1D线性标定
- 自标定
二
标定板介绍与制作
要想实现对相机的标定,我们首先需要给相机找到个参考对象,常见的就是标定版的类型有如下几种- Chessboard
- Circel-grid
- RandPattern
- ArUco
- ChArUc
三
制作标定版与图像生成
最简单的办法就是把上述图像直接打印出来,贴到一个塑料底板上就好啦。 如果是土豪可以直接购买各种玻璃底板的标定板。 另外还有一个更恶搞的方法,连打印都省啦,直接把chessboard.png这张图在另外一台电脑的显示器上显示,然后把摄像头对着它各种牌即可完成图像数据采集。 这个是我手写的采集程序代码,每次想保存图像的时候请安Q字母键即可,代码如下:
void create_images() {
Mat frame;
VideoCapture capture(0);
int index = 1;
while (true) {
bool ret = capture.read(frame);
flip(frame, frame, 1);
if (!ret) break;
imshow("frame", frame);
char c = waitKey(50);
printf("%d \n", c);
if (c == 113) { // Q
imwrite(format("D:/images/zsxq/%d.png", index), frame);
index += 1;
}
if (c == 27) {
break; // ESC
}
}
capture.release();
}
记得拿着棋盘格图,在镜头面前各种摆POSE,这个是属于你的表演时间,不要客气!具体参考下图:
四
相机标定程序实现
大家好,现在我们开始程序实现环节,OpenCV中在camera模块中已经实现了张正友标定算法。 我们只需要正确调用,就可以计算出相机的内参与外参,完成相机的标定。 具体的代码实现步骤如下: 定义相机标定的相关常量设置与变量
// load image filesvector<string> files;glob("D:/images/camera2d", files);// 定义变量vector<vector> imagePoints;vector<vector> objectPoints;TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 30, 0.001);int numCornersHor = 7;int numCornersVer = 7;int numSquares = 50;vector obj;for (int i = 0; i < numCornersHor; i++) for (int j = 0; j < numCornersVer; j++) obj.push_back(Point3f((float)j * numSquares, (float)i * numSquares, 0));
发现与绘制棋盘格位置
// 发现棋盘格与绘制Size s;for (int i = 0; i < files.size(); i++) { printf("image file : %s \n", files[i].c_str()); Mat image = imread(files[i]); s = image.size(); Mat gray; cvtColor(image, gray, COLOR_BGR2GRAY); vector corners; bool ret = findChessboardCorners(gray, Size(7, 7), corners, CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_FILTER_QUADS); if (ret) { cornerSubPix(gray, corners, Size(11, 11), Size(-1, -1), criteria); drawChessboardCorners(image, Size(7, 7), corners, ret); imagePoints.push_back(corners); objectPoints.push_back(obj); imshow("calibration-demo", image); waitKey(500); }}
发现棋盘格显示如下(我是直接打印OpenCV自带那张图的)
相机校正-计算内参数
// 相机校正Mat intrinsic = Mat(3, 3, CV_32FC1);Mat distCoeffs;vector rvecs;vector tvecs;intrinsic.ptr<float>(0)[0] = 1;intrinsic.ptr<float>(1)[1] = 1;calibrateCamera(objectPoints, imagePoints, s, intrinsic, distCoeffs, rvecs, tvecs);
五
畸变图像校正
关于畸变类型,常见的图像畸变类型有径向与切向畸变、OpenCV中的相机标定方法只能对径向畸变有效,使用内参对畸变图像实现校正。相关的代码如下:
// 畸变校正for (int i = 0; i < files.size(); i++) { Mat dst; Mat image = imread(files[i]); undistort(image, dst, intrinsic, distCoeffs); imshow("image", image); imshow("undistort image", dst); waitKey(1000);}
作者:gloomyfish
版权声明
本文版权归《OpenCV学堂》,转载请自行联系
历史文章推荐
CCAI 2019丨李德毅:自动驾驶泡沫破碎 技术、市场、生态和成本四个要素不可忽视
CCAI 2019丨张钹:为什么在人工智能上往往产生过于乐观估计?
CVPR2019 |《胶囊网络(Capsule Networks)综述》,附93页PPT下载
AiLearning:一个 GitHub万星的中文机器学习资源
深度学习中的数据增强方法总结
Multi-task Learning(Review)多任务学习概述
医学图像处理与深度学习入门
AI综述专栏 | 多模态机器学习综述
深度学习中不得不学的Graph Embedding方法
学习率和batchsize如何影响模型的性能?
旷视研究院新出8000点人脸关键点,堪比电影级表情捕捉
你正在看吗??