访问标定结果
算子calibrate_cameras的主要结果由相机内参和每一张图像标定板的位姿组成。算子将它们存储在标定数据模型中,可以用算子get_calib_data来访问它们。

相机外参并不能直接被获取,因为所需的世界坐标系统的信息没有存储在标定数据模型中。然而,如果标定板被直接放置在测量平面上,其位姿可以被用来很容易的得到相机的外参,其是测量平面的位姿。
确定相机外参
相机外参描述了测量平面和相机的关系,例如如果仅仅外参是已知,就可能将相机坐标系统(CCS)转化到测量平面的坐标系统,反之亦然。在HALCON中,测量平面被定义为世界坐标系统(WCS)z=0的平面。
相机外参可以用不同的方法来确定:
- 利用从某一个标定图像获取的位姿,其中标定图像中标定板被直接放置在测量平面上。在这种情况下,你就可以用算子get_calib_data来获得其位姿。
- 通过一个标定板被直接放置在测量平面的额外图像,将相机内参的确定从相机外参的确定分离出来。应用find_calib_object去提取标定标志点和位姿。
- 自己去确定3D世界点和它们在图像映射的对应关系,然后调用vector_to_pose。
如果你仅仅需要去精确地测量一个物体的尺寸,而不是在一个给定坐标系统的物体的绝对位置,前两种方法中一种就可以使用。
后两种情况具有相机外参的决定不依赖相机内参的优势。如果用单个相机在数个平面上做测量,或者不能在原地标定相机,这将是更加灵活和有用。
下面将对不同的情况做详细的讲解。
在标定图像之一将标定板放置在测量平面上
第一种情况是一种最容易决定外参的方法。标定板必须直接放置在测量平面上,例如流水线。
因为通过算子calibrate_cameras,标定板的位姿可以确定下来,你可以通过算子get_calib_data简单的访问其位姿。这样,用一个单一的标定步骤,内参和外参就能确定下来。这里,在第一个标定图像中标定板(标定物索引0)的位姿被确定。请注意的是每一个位姿是由7个值组成的。

如果标定把是无限的薄的,结果位姿将是测量平面的真实位姿。因为真实的标定板有一个厚度d>0,标定板的位姿通过一个垂直于测量平面的量d的移动,例如沿着WCS的z轴。为了矫正它,我们需要沿着WCS的z轴去移动位姿d个单位。为了执行这个移动,算子set_origin_pose被利用:

一般地,只要标定板和测量平面的空间关系是已知的,标定板在WCS中就可以任意地锁定方向(如图3所示)。然后,为了从标定板位姿中获得测量平面的位姿,一个刚性转换时必须的。在下面的例子中,标定板的位姿沿着y轴平移,接着绕着x轴旋转。

在一个单独图像中放置标定板在测量平面上
如果用HALCON标定板的优势可以将相机内参和外参分离所具有的灵活性相结合,第二种相机外参确定的方法可以使用。
首先,相机按照标定步骤进行标定。这可以优先于相机在最终使用点安装之前完成。
然后,在最终使用点安装完相机以后,外参就可以被确定。仅仅需要做的就是取一张图,图中标定被直接放在了测量平面上。从这张图中,外参就可以被确定下来。这里,内参,标定板被直接放在测量平面上的图像和标定标志点的世界坐标可从文件中读取。

然后,标定标志点和标定板的位姿被提取:

最后,考虑到标定板的厚度,被给相机位姿原点的值平移标定板厚度个单位。


图3 标定板和测量平面的关系
需要注意的是,如果你想将标定步骤分为两个部分来完成的话,相机的聚焦是很重要的,因为改变焦点就相当于改变焦距,其是内参的一部分。
利用已知的3D点和它们对应的图像点
如果在给定的世界坐标系统中执行测量是必要的,对于外参的确定,第三种情况就可以使用。这里,你需要知道至少不再一条直线上3个点的3D世界坐标,然后,你必须确定这些点映射后相对应的图像坐标。现在,算子vector_to_pose可以被用来确定相机的外参。
下面的程序作为一个确定外参的例子。
首先,三个点的世界坐标被设定。

然后,在图像上这些点映射后的图像坐标被确定。在这个例子中,它们被很简单的设定位一些接近的 值。实际上,它们应该以亚像素的精度确定下来,因为他们定义了相机外参。

最后,算子vector_to_pose在已知对应关系和相机内参的情况下,被调用。

从标定数据模型中删除观测图
为了确定有关标定的观测效果,或者从标定数据模型中移除坏质量的观测数据,可以用算子remove_calib_data_observ删除一个观测图。

当再次执行相机标定的时候,需要注意标定错误的改变。
保存结果和销毁标定数据模型
在访问结果(或者用算子write_cam_par和write_pose来存储它们),你可以借助算子clear_calib_data销毁标定数据模型。