点击我爱计算机视觉标星,更快获取CVML新技术


本文转载自OpenCV学堂。

OpenCV单目相机标定,图像畸变校正

相机标定定义与原理

01

在图像测量过程以及机器视觉应用中,为确定空间物体表面某点的三维几何位置与其在图像中对应点之间的相互关系,必须建立相机成像的几何模型,这些几何模型参数就是相机参数。在大多数条件下这些参数必须通过实验与计算才能得到,这个求解参数的过程就称之为相机标定(或摄像机标定)。相机标定常见的分为:

  • 单目相机标定

  • 双目相机标定

相机标定是想从二维的图像中获取三维信息,实现图像的畸变校正、对象测量、三维重建等。由于光线投射导致实际对象物体跟投影到2D平面的图像不一致,幸运的是这种不一致性是稳定的,我们可以通过对相机标定,计算出畸变参数来实现对后续图像的畸变校正。根据标定技术不一样可以分为下面几类标定方法:

  • 基于3D对象参照标定

  • 基于2D平面标定

  • 基于1D线性标定

  • 自标定

最常见的相机成像方式是基于pinhole的模型、它的成像模型可以图示如下:

下面我们首先对这个相机成像模型做一番解释

通过标定算法同时求出相机内参与外参。最常用的算法是张正友标定算法。OpenCV/Matlab中均已经实现该算法。

标定板介绍与制作

02

要想实现对相机的标定,我们首先需要给相机找到个参考对象,常见的就是标定版的类型有如下几种

  • Chessboard

  • Circel-grid

  • RandPattern

  • ArUco

  • ChArUc

OpenCV源码在其sample/data目录下面一个自带的棋盘图(chessboard.png),显示如下:

在标定的时候,算法要求提供的棋盘格的宽度高度,还有他们的间隔距离。需要特别注意是这里的宽高是指他们的内部交叉点的个数,以上图为例,它的大小为7x7而不是8x8。间隔是指棋盘格之间的距离,可以用像素距离表示,也可以用实际毫米为单位表示。

制作标定版与图像生成

03

最简单的办法就是把上述图像直接打印出来,贴到一个塑料底板上就好啦。如果是土豪可以直接购买各种玻璃底板的标定板。另外还有一个更恶搞的方法,连打印都省啦,直接把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) { // Qimwrite(format("D:/images/zsxq/%d.png", index), frame);index += 1;}if (c == 27) {break; // ESC}}capture.release();
}

记得拿着棋盘格图,在镜头面前各种摆POSE,这个是属于你的表演时间,不要客气!具体参考下图:

相机标定程序实现

04

大家好,现在我们开始程序实现环节,OpenCV中在camera模块中已经实现了张正友标定算法。我们只需要正确调用,就可以计算出相机的内参与外参,完成相机的标定。具体的代码实现步骤如下:

定义相机标定的相关常量设置与变量

// load image files
vector<string> files;
glob("D:/images/camera2d", files);// 定义变量
vector<vector<Point2f>> imagePoints;
vector<vector<Point3f>> objectPoints;
TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 30, 0.001);
int numCornersHor = 7;
int numCornersVer = 7;
int numSquares = 50;
vector<Point3f> 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<Point2f> 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<Mat> rvecs;
vector<Mat> tvecs;
intrinsic.ptr<float>(0)[0] = 1;
intrinsic.ptr<float>(1)[1] = 1;
calibrateCamera(objectPoints, imagePoints, s, intrinsic, distCoeffs, rvecs, tvecs);

畸变图像校正

05

关于畸变类型,常见的图像畸变类型有径向与切向畸变、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);
}


CV细分方向交流群

52CV已经建立多个CV专业交流群,包括:目标跟踪、目标检测、语义分割、姿态估计、人脸识别检测、医学影像处理、超分辨率、神经架构搜索、GAN、强化学习等,扫码添加CV君拉你入群,如已经为CV君其他账号好友请直接私信,

(请务必注明相关方向,比如:目标检测

喜欢在QQ交流的童鞋,可以加52CV官方QQ群:805388940。

(不会时时在线,如果没能及时通过验证还请见谅)


长按关注我爱计算机视觉

OpenCV相机标定与畸变校正相关推荐

  1. opencv相机标定(1)-畸变校正原理

    理想相机成像模型 看到一篇博客,介绍的十分详细.参考 链接 (为了好理解,个人还是喜欢分四大坐标系,世界坐标系,摄像机坐标系,图像物理坐标系,图像像素坐标系) 1)世界坐标系->摄像机坐标系 R ...

  2. 相机标定(三) —— 畸变校正

    一.前言 根据针孔模型,物体和成像之间参数会满足相似三角形的关系.但现实中会存在装配误差和透视失真等原因,导致这种关系无法成立,使理想成像与实际成像存在误差,这种误差即称为畸变. 畸变分为径向畸变,切 ...

  3. 手机广角相机标定和畸变校正

    摄像头或者相机会因为镜片的光学特性而发生有规律的变形或者畸变,包括桶型畸变,枕型畸变和线性畸变.普通相机的这些畸变十分轻微,人的肉眼几乎分辨不出,所以这时可以不需要校正.对于广角相机,鱼眼相机,由于视 ...

  4. 鱼眼摄像头标定与畸变校正(OPENCV版)

    转载请注明作者和出处:http://blog.csdn.net/u011475210 代码地址:https://github.com/WordZzzz/fisheye_calibration 软件版本 ...

  5. 鱼眼摄像头标定与畸变校正(双OPENCV版本)

    转载请注明作者和出处:http://blog.csdn.net/u011475210 代码地址:https://github.com/WordZzzz/fisheye_calibration 软件版本 ...

  6. opencv相机标定

    python 完整标注流程, python+opencv相机标定 - wenboz - 博客园 相机标定需要输出的参数: 焦距 像素或者物理单位mm 像素对应的物理长度 光心与物理senser中心的偏 ...

  7. python 正方形去畸变_opencv 角点检测+相机标定+去畸变+重投影误差计算

    https://blog.csdn.net/u010128736/article/details/52875137 https://blog.csdn.net/h532600610/article/d ...

  8. 相机标定之畸变矫正与反畸变计算

    相机标定之畸变矫正与反畸变计算 相机标定问题已经是比较成熟的问题,OpenCV中提供了比较全面的标定.矫正等函数接口.但是如果我想通过一张矫正好的图像,想获得原始的畸变图,却没有比较好的方法,这里讨论 ...

  9. OpenCv相机标定——圆形标定板标定

    OpenCv相机标定--圆形标定板标定 0.前言 1.标定图案 2.OpenCv标定 3.标定结果分析 0.前言   OpenCv中,相机标定所使用的标定图案分为棋盘格.对称圆形及非对称圆形特征图.A ...

最新文章

  1. EfficientNetv2测试
  2. lightoj 1044 - Palindrome Partitioning(需要优化的区间dp)
  3. OpenShift 4 - Knative教程 (3) 了解Knative Serving的核心对象
  4. P2661 信息传递 二分图的最小环
  5. vue 利用axios请求接口下载excel
  6. 构建java ut运行环境
  7. Altium Designer20下绘制封装、布局、布线及裁板等操作
  8. 边界类、控制类、实体类
  9. 基于ROS的AGV运动控制与状态记录(维嵌科技)
  10. tplink查看上网记录_Tplink路由器PPPOE拨号不能上网日志查看原因
  11. 伽罗华有限域_伽罗华域(Galois Field,GF,有限域)乘法运算 - MengBoy的专栏 - CSDN博客...
  12. colorsys模块(RGB/HSV/HSL/YIQ)颜色模型简介
  13. 2015CGMC 参赛游戏名单
  14. APP实现图片放大预览效果
  15. java pdf转png
  16. L0 Norm 、L1 Norm 和 L2 Norm 的简单理解
  17. python积木编程软件_童心制物慧编程全新 Python 编辑器正式上线
  18. Volley添加header发送请求
  19. 以色列AI营养数据公司获800万美元A轮融资
  20. 2021建筑施工电工(建筑特种作业)机考题库及建筑电工模拟试题

热门文章

  1. 三道小题带你了解SQL基本查询
  2. CubeMX 的使用实例详细(04.6)- STM32F103的 - 定时器设定 - callback调用 - 实现1S的定时更新LED灯
  3. 小程序基础 - wafer2 - PHP - 后台和前台 - 利用对象数组来传递表单数组的正确方法 - 下载部分(服务器到微信)
  4. linux 判断文件上传轨迹,linux各种常用命令
  5. python爬虫之request_Python爬虫:Scrapy研读之Request/Reponse
  6. super在python3和python2_python2与Python3的区别
  7. postgre 生成数据库html文档_postgresql数据库导入和导出CSV格式
  8. 民科微服务小程序怎么注册_民科微服务小程序(医师护士电子化注册系统入口)公众号...
  9. linux 自定义键盘布局,Ubuntu自定义键位xmodmap
  10. phpstudy的php fpm,PHP_php-fpm配置详解,php5.3自带php-fpm复制代码 代码 - phpStudy