勇哥先上程序,后面再解释:
list_files ('E:/calibration_image', 'files', ImageFiles) TmpCtrl_AllMarkRows := [] TmpCtrl_AllMarkColumns := [] TmpCtrl_StartPoses := [] TmpCtrl_ReferenceIndex := 0 StartParameters := [0.008,0,5.2e-006,5.2e-006,640,512,1280,1024] for Index := 0 to |ImageFiles|-1 by 1 read_image (Image, ImageFiles[Index]) find_caltab (Image, TmpObj_PlateRegion, 'E:/calibration_description/caltab_123mm.descr', 3, 112, 5) find_marks_and_pose (Image, TmpObj_PlateRegion, 'E:/calibration_description/caltab_123mm.descr', 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 caltab_points ('E:/calibration_description/caltab_123mm.descr', TmpCtrl_X, TmpCtrl_Y, TmpCtrl_Z) camera_calibration (TmpCtrl_X, TmpCtrl_Y, TmpCtrl_Z, TmpCtrl_AllMarkRows, TmpCtrl_AllMarkColumns, StartParameters, TmpCtrl_StartPoses, 'all', CameraParameters, TmpCtrl_FinalPoses, TmpCtrl_Errors) tuple_select_range (TmpCtrl_FinalPoses, 7*TmpCtrl_ReferenceIndex, 7*TmpCtrl_ReferenceIndex + 6, CameraPose) set_origin_pose (CameraPose, 0.0, 0.0, 0.001, CameraPose) stop ()
一、读入图像,函数如下
list_files ('E:/calibration_image', 'files', ImageFiles) for Index := 0 to |ImageFiles|-1 by 1 read_image(Image, ImageFiles[Index]) endfor
注释:'E:/calibration_image':为图像路径,图像文件索引是从0开始的,所以|ImageFiles|(文件数量)减去1。
二、提取图像Images中标定板上的圆形标志来确定标定板的有效区域,算子如下:
find_caltab(Image:Caltab:CalTabDescrFile,SizeGauss,MarkThresh,MinDiamMarks:)
确定标定板上圆形标志点的二维坐标,并得到摄像机外部参数的初始值,算子如下:
find_marks_and_pose (Image,CalTabRegion: :CalTabDescrFile ,StartCamParam , StartThresh,DeltaThresh,MinThresh,Alpha,MinContLength, MaxDiamMarks:Rcoord,Ccoord, StartPose)
注释:函数find_caltab在图像中寻找标定板是基于标定板的特征——在一个亮的区域中存在黑色标定点。
首先使用高斯滤波器进行图像平滑。参数SizeGauss确定高斯滤波器的尺寸。SizeGauss值越大进行图像平滑的幅度就越大,这在图像噪声比较大时是必要的。
在进行图像平滑操作后,为了寻找标定板的位置,我们进行一个阈值分割,可以参考灰度直方图,灰度值范围由最小值MarkThresh到最大值255,因此,MarkThresh必须小于标定板上白色区域的灰度值,并且最好大于图像中其他大范围较亮的区域的灰度值。
在阈值分割得到的多个区域中,其中包含孔的数量最符合标定板上标定点数量的凸状区域被选中。为了减少噪声影响,直径小于MinDiamMarks的孔将被除去。标志点的数量可以从标定板描述文件(CalTabDescrFile)中读出。
函数find_marks_and_pose提取标定板上各个标志点,并精确得到它们在图像坐标系中的坐标。
上面我们已经通过函数find_caltab找到了标定板的区域,这时我们首先在输入图像Image的这个区域(CalTabRegion)中应用边缘检测。这个边缘检测通过参数Alpha进行控制。Alpha的值越大 ,边缘检测的灵敏度也就越高,这将使边缘检测时找到更多的细节,但同时对噪声的抑制能力下降。
在边缘图像中,提取出封闭的轮廓线。为了更准确的寻找轮廓线,对边缘的振幅进行一个阀值操作。所有振幅高的点(标定点的边界)都被选中。首先,这个阀值设置为StartThresh。如果寻找封闭轮廓线或估计位姿失败,这个阀值接连地减DeltaThresh 直到阀值降低到最小值MinThresh。
闭合的轮廓线的数量必须与标定板描述文件(CalTabDescrFile)中描述的标志点的数量一致,并且这些闭合轮廓线的形状必须是椭圆状的。长度比MinContLength 短的轮廓线或者轮廓线形成区域的直径大MaxDiamMarks(如标定板的外框)的,这些轮廓线将被忽略抛弃。
三、保存坐标值
TmpCtrl_AllMarkRows := [] TmpCtrl_AllMarkColumns := [] TmpCtrl_StartPoses := [] TmpCtrl_AllMarkRows := [TmpCtrl_AllMarkRows, TmpCtrl_MarkRows] TmpCtrl_AllMarkColumns := [TmpCtrl_AllMarkColumns, TmpCtrl_MarkColumns] TmpCtrl_StartPoses := [TmpCtrl_StartPoses, TmpCtrl_EstimatedPose]
注释:标定点的在图像坐标系中的坐标存储在两个数组中,第一个数组存储所有点的行坐标,第二个数组存储所有点的列坐标,并
且要保证两个数组的值一一对应。这些数组的长度取决于标定板上标定点的个数以及拍摄的标定图像的数量。它们的存储顺序是
按照图像顺序排列的,也就是说刚开始的m个值存储的是第一幅图像中m个标定点的坐标值,这个顺序和函数caltab_points返回的数组X,Y,Z中的存储顺序是一致的。
四、摄像机标定输入参数
StartParameters := [0.008,0,5.2e-006,5.2e-006,640,512,1280,1024]
初始值摄像机标定是一个非常复杂的非线性优化的问题,因此就需要为摄像机的参数提供尽量精确的初始值。摄像机内部参数的初始值主要由CCD传感器和镜头的说明书确定。面阵摄像机的内参初始值可以输入一个
数 组 [f,k,Sx,Sy,Cx,Cy,NumColumns,NumRows]也就是说 ,不仅要提供摄像机的初始内参,还要提供图像的宽(NumColumns)和高(NumRows)。
五、确定摄像机的内参,误差分析,算子如下
camera_calibration(: :NX,NY,NZ,Nrow,Ncol,StartCamParam, NstartPose,EstimateParams:CamParam,NfinalPose,Errors)
函数如下:
caltab_points ('E:/calibration_description/caltab_123mm.descr', TmpCtrl_X, TmpCtrl_Y, TmpCtrl_Z) camera_calibration (TmpCtrl_X, TmpCtrl_Y, TmpCtrl_Z, TmpCtrl_AllMarkRows, TmpCtrl_AllMarkColumns,StartParameters, TmpCtrl_StartPoses, 'all', CameraParameters, TmpCtrl_FinalPoses, TmpCtrl_Errors)
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!

