其他分享
首页 > 其他分享> > 40.4、相机标定方法

40.4、相机标定方法

作者:互联网

相机:The Imaging Source(映美精)DFK 33GP 1300 面阵COMS相机。像元大小4.8 (微米) * 4.8 (微米)

镜头:Computar M3514-MP 焦距 = 35mm F=1.4

  1. 制作并生成标定板文件

*现有标定板7 * 7 的圆点标定点阵列,标定点中心距是3.2 mm,表定点圆直径1.6mm。用gen_caltab生成描述文件。

XNum:=7

YNum:=7

*单位是米

MarkDist:=0.0032

*直径与圆点间间距比值

DiameterRatio:=0.0016/0.0032

gen_caltab (XNum, YNum,MarkDist, DiameterRatio, 'caltab.descr', 'caltab.ps')

  1. 打开标定助手
  1. 打开"一"中生成的标定板描述文件
  2. 填写镜头的相关数据

    注:由前面说明的标定知识可以知道,摄像机模型用面扫描(多项式Polynomial)来做标定,效果更好

  1. 确定图像源并添加标定图像

1、选择图像文件,可以加载已保存在计算机中的标定板图像。

  1. 从相机上在线获取图像。

    注:(1)、选择"图像采集助手"后,会弹出右边的图形采集助手对话框,这时设置好图像采集助手的相关参数即

            可使用。

(2)、如果先事先就已经设置好了采集助手,再打开标定助手用"图像采集助手"关联的,那么在生成初始

    化采集过程代码时会提示:No acquisition initialization(must have acquisition assistant).处理方法:退出采集

    助手对话框,然后在选择标定助手中的"图像采集助手",然后在重新设置采集助手参数。

        (3)、设置后右边的图像采集助手后,打开实时采集。然后点击标定助手上的"采集"按钮是,即可把图像

                添加到列表中。

  1. 显示参数设置

    设置显示颜色

  1. 标定提取参数设置
  1. 这些参数用于提取定位标定板的,一般情况下,当采集到第一张标定图像时,这些参数会自动设置。但有时提起的效果不佳,需要手调。
  2. 定位标定板参数:首先根据高斯滤波尺寸进行高斯滤波去噪,通过表定点的最小直径对阈值的结果进行筛选,找到一个含 7 * 7 的空孔洞(标定板上的圆形标志点)区域,将标定板区域与背景分离开。下图"2"箭头所指区域(这里的参数只负责找到标定板区域)
  3. 提取标志点区域:由初始阈值开始,根据阈值递减设置的步长,自动尝试不同的阈值,进行阈值分割。直到7 * 7个圆心标志点得到标志点区域。下图"3"箭头所指区域(这里的参数只负责标志点区域)
  4. 提取标志点轮廓:找到标志点区域,进行平滑去噪,用亚像素边缘提取标定板各个圆形的边缘,通过最小轮廓长度虑除短的干扰轮廓。因为圆标志点的投影为椭圆,用拟合椭圆的算法把所有提取出的边缘拟合为椭圆。通过最大标志点直径,对拟合出来的椭圆进行筛选,虑除直径过大的椭圆。

  1. 品质问题

由于光源照的不够均匀,标定板没有放在最清晰平面,加载的标定的图片太少等因素。会引起标定质量不佳。Halcon标定助手中会提示相关的问题。这些问题警告级别默认是70%,当这个品质问题大于70%才会消失。

  1. 品质问题1:视野没有完全被标定板覆盖到

    由于图片太少,整个视野中有些地方没有被标定板覆盖。可以点击后面的"show"按钮,出现下图,绿色区域表示该区域已被标定板覆盖,绿色越深,表示越靠近标定板,矫正效果越好。红色表示该区域没有 被标定板覆盖,红色越深,表示离标定板越远。

    注:当点击"show"显示这个绿红区域时,要点击界面中的"更新"按钮画面才会切换到标定图片。

  2. 品质问题2:旋转角度没有被先后覆盖到

    将相机进行标定得到的是相机与二维测量平面的位姿,旋转角度、深度时候被覆盖对于二维测量平面标定来说不是最重要的,它们的作用是优化相机参数,如果能覆盖尽量多的角度、深度,当然更好。

  3. 其他品质问题:

    如品质评估出错、检测出某些图片品质有问题等一些品质问题,通过调"五、标定提取参数设置"的参数很难把这些品质问题去掉,解决方案是,通过相机实时采集图片,改变灯光亮度、景深大小等外部环境,进到标定中显示"确定"字样,而不是"检测出品质问题"时,就采集这张图像作为标定图像。

出现品质问题时,可以从以下几个方面来改进:

(1)、使用标定板的有效区域(黑色方框区域)要足够大,尽量在视野的1/4以上

(2)、圆心标志点的最小直径不能低于10个pix

(3)、标定板为白色背景,黑色的圆心标志点和黑色边框

(4)、标定板的白色背景的灰度值不能低于100

(5)、黑色标志点和边框与白色背景的灰度对比度最好大于100

(6)、使用均匀的光源照明

(7)、图像不能过曝

(8)、要用尽量多的图像来覆盖整个视野,图像越多越好,覆盖图像的四个角,这主要原因是角落处的镜头畸变最大,

    这样可以得到畸变系数最准确的值。

(9)、在景深范围内发改各种旋转角度和尽量多的深度,可以通过标定板绕它的x轴和y轴旋转或者将标定板放置在

        与相机不懂距离的位置上。

(10)、用于标定的有效图像尽量不低于10张,最好在10到20张图像,图像越多越好

(11)、标定好后,相机和镜头不能动,若果再调节相机和镜头、调节镜头的光圈、焦距,调节后需要重新标定。

(12)、在任何情况下只要相机

  1. 设置参考位姿

如果在用来标定的其中一幅图像中的标定板直接放在测量平面(如传送带),那么这幅图像中标定板的外参基本等同于测量平面的位姿。选取一张图像,该图像中的标定板尽量在视野中间,而且图像横平竖直的对齐。如下图,点击后前面有个"*",表示以当前图像的位姿作为参考位姿,点击标记即可标定完成。

注:若没有选定,则系统自动选择这个列表图像中的第一张作为参考位姿.

  1. 结果

1、通过上述步骤,点击"标定"按钮后,页面即跳到"结果"中。可以点击保存按钮保存相关参数。

2、显示坐标系轴表示时候显示坐标轴图形

3、选择"模拟的参考图像":会根据参考图像以及halcon标定板的规则,产生一个模拟的halcon标定板参考图像。

  1. 代码生成
  1. 标定:

    (1)、图中1处的两个文件就是"八、结果"中的保存的两个文件

    (2)、生成模式:

                标定函数

                    使用标定模型,在此模式下才有用,勾选,表示基于句柄的标定算子,不勾选表示使用基于非句柄

                    的标定算子

                标定数据(Tuple)

                    把标定的相机参数和位姿以Tuple的数据形式插入代码(不需要勾选初始化采集过程和使用标定模型)

                标定数据(File)

                    设置好保存参数文件和位姿文件的路径,插入代码(不需要勾选初始化采集过程和使用标定模型)

                    程序会安装好的路径保存参数文件和位姿文件,然后再一算子读取文件形式加载参数文件和位姿文

                    件:

例子1:选择"标定函数"时插入代码

以下使用的函数在《40.5、Calibration Function》介绍

==============================******不勾选使用标定模型**********==============================

 

* Code generated by Calibration 01

ImageFiles := []

ImageFiles[0] := 'H:/biaoding/BDpicture/image_01.png'

.

.

.

.

ImageFiles[84] := 'H:/biaoding/BDpicture/image_86.png'

TmpCtrl_AllMarkRows := []

TmpCtrl_AllMarkColumns := []

TmpCtrl_StartPoses := []

TmpCtrl_ReferenceIndex := 9

TmpCtrl_PlateDescription := 'H:/biaoding/标定板制作/caltab.descr'

*这里的参数的个数内部就会自动选择标定算法为'area_scan_polynomial'

StartParameters := [0.035,0,0,0,0,0,4.8e-006,4.8e-006,640,480,1280,960]

* Collect mark positions and estimated poses for all plates

for Index := 0 to |ImageFiles| - 1 by 1

*读入图像

read_image (Image, ImageFiles[Index])

*输入标定板描述文件,查找标定板,结果只输出一个标定板的区域TmpObj_PlateRegion

find_caltab (Image, TmpObj_PlateRegion, TmpCtrl_PlateDescription, 3, 112, 5)

*输入 标定板区域、标定板描述文件(主要利用该标定板有多少行多少列)、初始相机参数

*输出该图像每个标志点的像素坐标,和该图片的位姿

find_marks_and_pose (Image, TmpObj_PlateRegion, TmpCtrl_PlateDescription,

StartParameters, 128, 10, 18, 0.9, 15, 100, TmpCtrl_MarkRows, TmpCtrl_MarkColumns, TmpCtrl_EstimatedPose)

*把计算出的该图像的所有标志点像素坐标存入到点数组中

TmpCtrl_AllMarkRows := [TmpCtrl_AllMarkRows, TmpCtrl_MarkRows]

TmpCtrl_AllMarkColumns := [TmpCtrl_AllMarkColumns, TmpCtrl_MarkColumns]

*把计算出的该图像位姿存入到数组中

TmpCtrl_StartPoses := [TmpCtrl_StartPoses, TmpCtrl_EstimatedPose]

endfor

* 解析标定板(该标定板有多少行、多少列、以及每个点的真实坐标单位m)

caltab_points (TmpCtrl_PlateDescription, TmpCtrl_X, TmpCtrl_Y, TmpCtrl_Z)

*输入解析标定板得到的数据、所有标定板图像中的像素点坐标、所有标定板图像的位姿

*输出相机内参CameraParameters,N组矫正后的位姿TmpCtrl_FinalPoses(一张图像对应一个位姿),误差

camera_calibration (TmpCtrl_X, TmpCtrl_Y, TmpCtrl_Z, TmpCtrl_AllMarkRows,

TmpCtrl_AllMarkColumns, StartParameters, TmpCtrl_StartPoses, 'all', CameraParameters, TmpCtrl_FinalPoses, TmpCtrl_Errors)

*从N组矫正后的位姿TmpCtrl_FinalPoses选出一个来设置为参考位置。

* 也就是上面的《七、设置参考位姿》

tuple_select_range (TmpCtrl_FinalPoses, 7*TmpCtrl_ReferenceIndex, 7*TmpCtrl_ReferenceIndex

+ 6, CameraPose)

* Adjust origin for plate thickness

set_origin_pose (CameraPose, 0.0, 0.0, 0, CameraPose)

stop ()

注:

初始化的StartParameters := [0.035,0,0,0,0,0,4.8e-006,4.8e-006,640,480,1280,960]

分别是:焦距、径向2阶(k1)、径向4阶(k2)、径向6阶(k3) 、切向2阶(p1) 、切向2阶(p2)、图像宽度一半、图像高度一半、图像宽度、图像高度。(径向切向赋值为0,调用标定函数后会自动计算出来)

 

最终标定出来的内参数会修改StartParameters里的数据。

 

 

==============================******勾选使用标定模型**********==============================

* Code generated by Calibration 01

ImageFiles := []

ImageFiles[0] := 'H:/biaoding/BDpicture/image_01.png'

.

.

.

.

ImageFiles[84] := 'H:/biaoding/BDpicture/image_86.png'

TmpCtrl_ReferenceIndex := 9

TmpCtrl_PlateDescription := 'H:/biaoding/标定板制作/caltab.descr'

StartParameters := [0.035,0,0,0,0,0,4.8e-006,4.8e-006,640,480,1280,960]

* Create calibration model for managing calibration data

create_calib_data ('calibration_object', 1, 1, CalibHandle)

*指定标定算法

set_calib_data_cam_param (CalibHandle, 0, 'area_scan_polynomial', StartParameters)

*把标定板描述文件存入到句柄中

set_calib_data_calib_object (CalibHandle, 0, TmpCtrl_PlateDescription)

* Collect mark positions and estimated poses for all plates

for Index := 0 to |ImageFiles| - 1 by 1

*读入图像

read_image (Image, ImageFiles[Index])

*输入标定板描述文件,查找标定板,结果只输出一个标定板的区域TmpObj_PlateRegion

find_caltab (Image, TmpObj_PlateRegion, TmpCtrl_PlateDescription, 3, 112, 5)

*输入 标定板区域、标定板描述文件(实际距离)、初始相机参数

*输出该图像每个标志点的坐标(主要利用该标定板有多少行多少列),和该图片的位姿

find_marks_and_pose (Image, TmpObj_PlateRegion, TmpCtrl_PlateDescription,

StartParameters, 128, 10, 18, 0.9, 15, 100, TmpCtrl_MarkRows, TmpCtrl_MarkColumns, TmpCtrl_EstimatedPose)

*把计算出的该图像的所有标志点像素坐标和位姿存入句柄CalibHandle中

set_calib_data_observ_points (CalibHandle, 0, 0, Index, TmpCtrl_MarkRows,

TmpCtrl_MarkColumns, 'all', TmpCtrl_EstimatedPose)

endfor

* 根据句柄标定

calibrate_cameras (CalibHandle, TmpCtrl_Errors)

*从句柄中取得相机内参

get_calib_data (CalibHandle, 'camera', 0, 'params', CameraParameters)

*从句柄中取得一个位姿坐标参考位姿

* 也就是上面的《七、设置参考位姿》

get_calib_data (CalibHandle, 'calib_obj_pose', [0, TmpCtrl_ReferenceIndex], 'pose', CameraPose)

* Adjust origin for plate thickness

set_origin_pose (CameraPose, 0.0, 0.0, 0, CameraPose)

* Clear calibration model when done

clear_calib_data (CalibHandle)

stop ()

 

 

例子2:选择"标定数据(Tuple)"时插入代码

*标定好的相机参数直接用一个数组表示

CameraParameters := [0.0850467,-1379.79,4.54827e+007,-5.227e+011,0.183187,-0.284907,4.90908e-006,4.8e-006,533.741,1326.16,1024,1280]

*标定好的相机位姿参数直接用一个数组来表示

CameraPose := [-0.000599182,-0.0213888,0.580617,4.30312,2.76294,180.297,0]

stop ()

 

例子3:选择"标定数据(File)"时插入代码

* 标定好的相机参数直接从文件读取,改文件就是<八、结果>中保存的文件

read_cam_par ('C:/biaoding/GrayImg/Cam_param.cal', CameraParameters)

* 标定好的相机位姿参数直接从文件读取

read_pose ('C:/biaoding/GrayImg/Cam_pos.dat', CameraPose)

stop ()

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

标签:标定,40.4,TmpCtrl,相机,图像,位姿,标志点
来源: https://www.cnblogs.com/ihh2021/p/16332839.html