视点!OpenCV之摄像机标定

2023-04-21 02:06:43 来源:QT教程

最近方向定下来是双目立体视觉,主要是做重建这块的研究。大致过程是图像获取->摄像机标定->特征提取->匹配->三维重建,当然开始可以进行图像预处理,矫正,后期可以进行点云的进一步处理,如渲染表面使其更接近于现实物体。

图像获取相对来说比较简单,用相机拍摄目标物(大型场景或特定小型的室内物体)。但有两点需要注意:


【资料图】

1、双目重建所需的图像一般为两张,角度相差不应过大,否则公共部分太少以至于重建效果不佳;整个过程简便,成本也不高,但缺陷是只有两张图像的点云所表示的物体信息不会很全面;

2、标定所需的图像又是另外拍摄的,用张正友标定法的话,把印有黑白棋盘格的图像粘至硬纸板上,然后左右摄像机各自进行拍摄,理论上获得角度(图像)越多,最终标定结果越精确;标定板见下图:

这里主要结合OpenCV对左右摄像机标定做一个简单的介绍,望朋友们指正,一起交流、进步。

摄像机的标定问题是机器视觉领域的入门问题,可以分为传统的摄像机定标方法和摄像机自定标方法。定标的方法有很多中常见的有:Tsai(传统)和张正友(介于传统和自定标)等,

摄像机成像模型和四个坐标系(通用原理)。

摄像机模型采用经典的小孔模型,如图中Oc(光心),像面π表示的是视野平面,其到光心的距离为f(镜头焦距)。

四个坐标系分别为:世界坐标系(Ow),摄像机坐标系(Oc),图像物理坐标系(O1,单位mm),图像像素坐标系(O,位于视野平面的左上角,单位pix)。

空间某点P到其像点p的坐标转换过程主要是通过这四套坐标系的三次转换实现的,首先将世界坐标系进行平移和转换得到摄像机坐标系,然后根据三角几何变换得到图像物理坐标系,最后根据像素和公制单位的比率得到图像像素坐标系。(实际的应用过程是这个的逆过程,即由像素长度获知实际的长度)。

ps:通过摄像头的标定,可以得到视野平面上的mm/pix分辨率,对于视野平面以外的物体还是需要通过坐标转换得到视野平面上。

转化的过程和公式参见:摄像机标定原理(关键是三个坐标系).ppt

2 张正友算法的原理

zhang法通过对一定标板在不同方向多次(三次以上)完整拍照,不需要知道定标板的运动方式。直接获得相机的内参(参考文献上矩阵A)和畸变系数。该标定方法精度高于自定标法,且不需要高精度的定位仪器。

ZHANG的算法包含两个模型:一.经典针孔模型,包含四个坐标系,二畸变模型(这个来源未知)

公式三项依次表示,径向畸变,切线畸变,薄棱镜畸变。OPENCV中函数只能给出k1,k2,p1,p2。

还存在另外一种畸变模型,见《摄像机标定算法库的设计和试验验证》一文26 page。

张正友标定有matlab的工具箱TOOLBOX_CAL,以及OpenCV库,下面是C++结合OpenCV的代码:

1 #include "cvut.h"  2 #include 3 #include 4 #include 5 using namespace cvut;  6 using namespace std;  7 void main()   8 {  9      ifstream fin("calibdata.txt"); 10      ofstream fout("calibration_result.txt");  11      //****************开始提取角点***********************// 12      cout<<"开始提取角点………………"; 13      int image_count=0;  14      CvSize image_size;  15      CvSize board_size = cvSize(5,7);    16      CvPoint2D32f * image_points_buf = 17                 new CvPoint2D32f[board_size.width*board_size.height];   18      Seqimage_points_seq;  19      string filename; 20      while (std::getline(fin,filename)) 21      { 22           cout<<"
 将鼠标焦点移到标定图像所在窗口" 23           <<"并输入回车进行下一幅图像的角点提取 
"; 24           image_count++; 25           int count; 26           Imageview(filename);  27           if (image_count == 1) 28           { 29                image_size.width = view.size().width; 30                image_size.height = view.size().height; 31           } 32           if (0 == cvFindChessboardCorners( view.cvimage, board_size, 33                 image_points_buf, &count, CV_CALIB_CB_ADAPTIVE_THRESH )) 34           { 35                 cout<<"can not find chessboard corners!
"; 36                 exit(1); 37           } 38           else 39          { 40            Imageview_gray(view.size(),8,1); 41            rgb2gray(view,view_gray); 42            cvFindCornerSubPix( view_gray.cvimage,  43            image_points_buf, count, cvSize(11,11), 44            cvSize(-1,-1),  45            cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 )); 46            image_points_seq.push_back(image_points_buf,count); 47            cvDrawChessboardCorners( view.cvimage, board_size,  48                     image_points_buf, count, 1); 49            view.show("calib"); 50            cvWaitKey();  51            view.close(); 52          } 53      }//角点提取循环 54      delete []image_points_buf;  55      cout<<"角点提取完成!
"<object_points(1, 59                 board_size.width*board_size.height*image_count,3); 60      Matriximage_points(1,image_points_seq.cvseq->total,2); 61      Matrixpoint_counts(1,image_count,1); 62      Matrixintrinsic_matrix(3,3,1); 63      Matrixdistortion_coeffs(1,4,1); 64      Matrixrotation_vectors(1,image_count,3); 65      Matrixtranslation_vectors(1,image_count,3); 66      int i,j,t; 67      for (t=0;ttotal,str,10); 81      cout<total;i++) 83      { 84             image_points(0,i,0) = image_points_seq[i].x; 85             image_points(0,i,1) = image_points_seq[i].y; 86      } 87      for (i=0;iimage_points2(1,point_counts(0,0,0),2);135      int temp_num  = point_counts(0,0,0); 136      cout<<"	每幅图像的定标误差:
";137      fout<<"每幅图像的定标误差:
";138      for (i=0;irotation_vector(3,1);176      Matrixrotation_matrix(3,3);177      fout<<"相机内参数矩阵:
";178      fout<

这段程序可以直接运行,本人是在vs2010+OpenCV2.4.0环境下,配置在前面文章中有介绍。标定板图像序列名称放在文件"calibdata.txt"中,每行一幅图像名,路劲问题这里就不论述了。如

image/chess1.jpg image/chess2.jpg

……

最后标定结果存储在"calibration_result.txt"中,命令行窗口也会显示一些信息。观察结果会发现,摄像机内参数矩阵M1和畸变系数k1,k2,p1,p2是直接调用OpenCV中标定函数求解出的,以及每幅图像相对于对应摄像机成像平面的旋转矩阵R"(或旋转向量)和平移向量t",而不是世界坐标系相对于摄像机坐标系,也不是两部摄像机之间的空间关系。而对于外参[R t],一直都是很抽象的问题。

在重建的过程中,主要需要两个元素:

1、摄像机内M1、外参数M2(或者说是投影矩阵M=M1*M2)

2、左右成像平面上的匹配特征点对

最后通过视差原理计算出物体上特征点对应的空间点坐标,得到最终点云。

当然,有兴趣的可以继续学习、研究下去,外参可以通过图像上的点和预先得到的世界坐标系下的物体上的空间点坐标,利用一系列数学关系计算。

在实际操作中,可以在重建过程进行自标定,即不用分别进行标定求得摄像机参数,而是直接通过特征点对计算投影矩阵,后面步骤同上。当然自标定得到的结果精度不是很高,目前较多的是上面所述的张正友标定法,介于传统与自标定之间。

【领 QT开发教程 学习资料, 点击下方链接莬费领取↓↓ ,先码住不迷路~】

点击这里:

标签:

视点!OpenCV之摄像机标定

2023-04-21

郑州初中生转学条件是什么?_即时焦点

2023-04-21

今亮点!国产新车报道:新款开瑞K60EV上市 补贴后售12.88-13.88万

2023-04-21

海保人寿益盛长盈终身寿险条款解析,值得投保吗?产品特色好不好?

2023-04-21

公共 | 京津冀图书馆青少年阅读推广北京地区活动启动_环球微速讯

2023-04-21

索朗曲扎:戍守西藏阿里典角村,“我就是这里的监控探头”

2023-04-21

世界最资讯丨抖音新晋顶流“盛唐密盒”爆火 00年“房玄龄”穿特制靴子2米多高

2023-04-21

微软DirectStorage加速技术升级1.2:老机械盘打一管鸡血 环球微资讯

2023-04-21

达志科技:目前第二条新能源电池生产线仍处于安装调试阶段 _每日消息

2023-04-20

每日观察!中国人寿上海市分公司总经理王忠伟:聚焦重点难点问题 多措并举全力做好消费者权益保护工作

2023-04-20

全球观天下!西藏职业技术学院国家级创新创业学院正式揭牌

2023-04-20

贺州市农业农村局举办胶体金快速检测培训班

2023-04-20

当前动态:超值价!RTX 4070现货4499元

2023-04-20

《咸鱼之王》通天孙策打法攻略

2023-04-20

环球热推荐:《圣斗士星矢》真人电影新剧照 众多明星帅气登场

2023-04-20

腾讯否认减持快手,但仍未打消投资者疑虑

2023-04-20

农业农村部种植业管理司潘文博:严禁各类毁坏青苗行为

2023-04-20

国产芯片龙头企业长鑫存储计划登陆科创板,估值逾千亿人民币

2023-04-20

ST泰禾:公司于2023年1月31日依照监管要求披露了业绩预告

2023-04-20

走之旁的字有哪些_盘点走之旁的字有什么

2023-04-20

天天最资讯丨嘉兴市一仓库发生火灾:火势已基本得到控制,无人员被困

2023-04-20

IPO参考:扬杰科技GDR在瑞士上市交易 北京长峰医院火灾停牌-当前头条

2023-04-20

热点评!青海2023年3月份电力市场化交易电量情况

2023-04-20

财政部:一季度全国住房保障支出增长9% 公共预算支出同比增6.8% 微速讯

2023-04-20

世界今日讯!海新能科:4月19日召开业绩说明会,投资者参与

2023-04-20

旺能环境(002034.SZ)发一季度业绩,净利1.64亿元,同比下降3.00%|焦点热闻

2023-04-20

【天天播资讯】VersalHBM系列外部参考时钟设计指南

2023-04-20

【地评线】紫金e评:智力运动让生活更美好 当前滚动

2023-04-20

天天要闻:徐州市铜山区成立产业链综合党委 以党建引领联动发展

2023-04-20

世界观热点:美国政客在乎的很多 其中偏偏没有民众的性命

2023-04-20

Copyright ©  2015-2022 北方频道网版权所有  备案号:京ICP备2021034106号-50   联系邮箱: 55 16 53 8@qq.com