一、自标定含义和意义
摄像机自标定方法不需要标定块,只是通过摄像机在运动过程中建立多幅图像之间对应的关系,直接进行标定,它克服了传统标定方法的缺点,灵活性较强,它的缺点是标定过程复杂,使用非线性方法标定,鲁棒性差,精度也不高。现在已有的自标定技术大致可以分为:基于 Kruppa 方程的自标定方法、基于二次曲面的自标定方法、分层逐步标定法等。
在项目中,偶尔会遇到由于产品形状、拍摄位置等原因导致标定板很难放置的情况,此时可以考虑使用halcon自标定算法来标定相机。
halcon提供了一种自标定的算子,它可以在不用标定板的情况下,只需要一张图片,根据提取到是物体边缘的直线,来得到相机的内参,标定出相机内参(无焦距),从而完成畸变校正,因为畸变一般在图像的边缘更严重,所以需要保证在图像的四周边缘有足够的直线线段。在实际项目中拍摄物体不可能都像例程中一样有理想的直线边缘,替代方法是:用菲林片制作一张网格黑色印制(10*10,可以根据自己实际情况调整)充满整个视野。
求出了相机内参就可以进行畸变校正,因而自标定相对于采集多张标定板图像进行标定而言,在畸变校正方面更快捷,极大地方便在设备现场进行调试,但是相对于标定板标定而言,无法求出相机的外参。
后续若需要将像素单位换算至公有制单位,也可使用棋盘格、标准物、菲林片等进行转换,便可应用于测量项目;也可以利用一定网格构建XY坐标系,用于定位项目,这样在不借助标定板的情况下就可以畸变校正和测量类的项目。
二、自标定流程:
1.求出拍摄物体的边缘XLD
2.使用radial_distortion_self_calibration函数,根据边缘求出相机内参
3.change_radial_distortion_cam_par 求出理想无畸变内参
4.change_radial_distortion_image 根据相机内参,对图像进行畸变校正
代码:
* 使用edges_sub_pix 或line_gauss提取图像边缘轮廓 edges_sub_pix (Image, Edges, 'canny', 1, 10, 40) * 分割直线和圆弧 segment_contours_xld (Edges, SplitEdges, 'lines_circles', 5, 4, 2) * 选择对校准有用的足够长的边 select_shape_xld (SplitEdges, SelectedEdges, 'contlength', 'and', 30, 100000) * 根据一组XLD轮廓估计镜头的畸变参数和畸变中心,以此达到校准径向畸变的目的 radial_distortion_self_calibration (SelectedEdges, CalibrationEdges, Width, Height, 0.08, 42, 'division', 'variable', 0, CamParSingleImage) * 根据radial_distortion_self_calibration的结果,您可以通过将包含畸变参数的参数CameraParam传递给操作符change_radial_distortion_cam_par和change_radial_distortion_image来对图像进行校正,即去除径向畸变 get_domain (Image, Domain) change_radial_distortion_cam_par ('fixed', CamParSingleImage, 0, CamParSingleImageRect) change_radial_distortion_image (Image, Domain, ImageRectified, CamParSingleImage, CamParSingleImageRect) write_cam_par (CamParSingleImage, 'C:/Users/Administrator/Desktop/CamParSingleImage.dat') write_cam_par (CamParSingleImageRect, 'C:/Users/Administrator/Desktop/CamParSingleImageRect.dat') read_cam_par ('C:/Users/Administrator/Desktop/CamParSingleImage.dat', CamParSingleImage) read_cam_par ('C:/Users/Administrator/Desktop/CamParSingleImageRect.dat', CamParSingleImageRect)
三、核心函数:
核心算子一:radial_distortion_self_calibration( Contours : SelectedContours : Width, Height, InlierThreshold, RandSeed, DistortionModel, DistortionCenter, PrincipalPointVar : CameraParam ) —— 根据一组XLD轮廓估计镜头的畸变参数和畸变中心,以此达到校准径向畸变的目的
对畸变的评估是基于图像中可见大量直线的假设。由于透镜畸变,这些线将被投影成曲线轮廓。操作者现在可以确定适当的参数,通过这些参数,曲线轮廓可以被再次拉直,从而补偿透镜的畸变。
要获得合适的输入轮廓,可以使用edges_sub_pix或lines_gauss。轮廓应该是均匀分布的,并且应该位于图像边界附近,因为那里的失真程度是最大的,因此校准是最稳定的。为了提高速度和健壮性,您可以尝试获得长线性或圆形段,例如使用segment_contours_xld、union_collinear_contours_xld、union_cocircular_contours_xld或select_shape_xld。如果一个单独的图像在场景中没有包含足够的直线轮廓,你可以使用多个图像的轮廓。
操作员使用鲁棒RANSAC方法自动从场景中直线图像的轮廓中估计出这些轮廓。不满足这个条件,因此不适合校准过程的轮廓称为离群值。操作符可以处理最大的异常值百分比为50%。经过畸变校正后,如果轮廓与相关直线的平均偏差大于给定的阈值T,则将轮廓归为离群值。
InlierThreshold值描述包含100个点的轮廓从其关联线的平均偏差,以像素为单位。实际阈值T由InlierThreshold根据参考长度(100)和轮廓点个数m进行缩放得到,因此相似的轮廓分类相似。典型的InlierThreshold值在0.05到0.5之间。值越高,越能容忍偏差。
通过参数RandSeed,你可以控制随机行为的RANSAC算法,并迫使它返回可重复的结果。该参数作为初始值传递给内部使用的随机数生成器。如果将其设置为正值,操作符将为每个调用返回相同的结果,并具有相同的参数值。
参数列表:
Contours (in):可用于校准的等高线(图像中提取到轮廓线)
SelectedContours (out):用于校准的等高线(在图像中提取到轮廓线中筛选出符合条件的轮廓线)
Width(in):提取轮廓的图像的宽度
Height(in):提取轮廓的图像的高度
InlierThreshold(in):异常值分类的阈值:
RandSeed(in):随机种子
DistortionModel(in):畸变模式
DistortionCenter(in):决定使用何种方式估计失真中心。有 ‘variable’(默认,适用于图像边缘轮廓线很多或者失真应该很高。否则,在寻找畸变中心时可能会出现不适定性,从而导致不稳定性。)‘adaptive’(如果可以假定畸变中心位于图像中心附近,并且只有很少的等值线可用或其他等值线的位置不好(例如等值线方向相同),则应使用这种方法), ‘fixed’(该方法适用于失真很弱或轮廓线少的情况下,在不好的位置。)
PrincipalPointVar (in):偏差控制,控制畸变中心与图像中心的偏差
CameraParam (out):输出相机内部参数
核心算子二:change_radial_distortion_cam_par( : : Mode, CamParamIn, DistortionCoeffs : CamParamOut) —— 根据指定的径向畸变确定新的相机参数。
参数列表:
Mode (in):模式 ( 注: ‘fixed’ 要比 ‘adaptive’ 稳定)
CamParamIn (in):相机内部参数(原图)
DistortionCoeffs(in):所需的径向扭曲
CamParamOut(out):相机内部参数(已修改)
核心算子三:change_radial_distortion_image(Image, Region : ImageRectified : CamParamIn, CamParamOut : ) —— 改变图像的径向畸变。
change_radial_distortion_image根据摄像机内部参数CamParamIn和CamParamOut对输入图像图像的径向畸变进行改变。使用CamParamOut将位于区域区域内的输出图像的每个像素转换为图像平面,然后使用CamParamIn将其投影为图像的亚像素。通过双线性插值确定得到的灰度值。如果该亚像素在图像之外,则将图像重建中的对应像素设置为“黑色”并从图像域中消除。
参数列表:
Image (in):原始图像
Region (in):成像重建感兴趣的区域。
ImageRectified(out):畸变校正之后的图像
CamParamIn(in):内部相机参数。
CamParamOut(in):内部相机参数(已修改)。
戳戳小手帮忙点个免费的赞和关注吧,嘿嘿。 |