Halcon标定步骤
1.设置相机内部参数的初始值
StartCamPar := [0.016,0,0.0000074,0.0000074,326,247,652,494]
set_calib_data_cam_param (CalibDataID, 0, ‘area_scan_division’, StartCamPar)
1.1 相机型号
- (1)面阵
- (2)线阵
1.2 参数设置(这里只讲面阵相机)
- (1)Division 畸变模型
CameraParam:[Focus, Kappa, Sx, Sy, Cx, Cy, ImageWidth, ImageHeight] - (2)Polynomial 畸变模型
CameraParam:[Focus, K1, K2, K3, P1, P2, Sx, Sy, Cx, Cy, ImageWidth, ImageHeight]
注:当镜头为远心镜头时,Focus=0;
1.3 畸变类型的选择
- Division 畸变模型只适用于精度要求不是很高,标定图片数量较少的情况;Polynomial 畸变模型对镜像
畸变和切向畸变都校正,精度较高,花费时间长。
1.4 标定时个参数值的确定技巧
- Focus f:镜头的标称焦距,( e.g, 0.016 m; 对于远心镜头为0。)
- κ: 一般去0.0
Or:
-
K1, K2, K3,P1, P2:可全部初始化为0
-
Sx: 由CCD\CMOS确定建议取值如下:
Full image (640480) Subsampling (320240)
1/3"-Chip 0.0000055 m 0.0000110 m
1/2"-Chip 0.0000086 m 0.0000172 m
2/3"-Chip 0.0000110 m 0.0000220 m -
Sy: 由CCD\CMOS确定建议取值如下:
for example:
Full image (640480) Subsampling (320240)
1/3"-Chip 0.0000055 m 0.0000110 m
1/2"-Chip 0.0000086 m 0.0000172 m
2/3"-Chip 0.0000110 m 0.0000220 m -
Cx and Cy: 光心坐标初始值,建议取值如下:
for example:
Full image (640480) Subsampling (320240)
Cx 320.0 160.0
Cy 240.0 120.0 -
ImageWidth,ImageHeight:有实际图片大小来初始化该值
for example:
Full image (640480) Subsampling (320240)
ImageWidth 640 320
ImageHeight 480 240
2.标定板初始化
CaltabName := 'caltab_30mm.descr'//标定板描述文件
set_calib_data_calib_object (CalibDataID, 0, CaltabName)
3.创建数据模型
create_calib_data ('calibration_object', 1, 1, CalibDataID)
4.获取标定图片
相机拍摄不同位姿下图片8-15张,拍摄图片时标定板尽量覆盖整个视场(标定板要根据工作距离、视场大小定制);拍摄图片上的圆直径不得小于10个像素
#### 5.加载所有图像,寻找标定板区域,确定圆心,将结果加载到组元中
for I := 1 to NumImages by 1
... acquire image ...(获取图像)
find_caltab (Image, Caltab, CaltabName, SizeGauss, MarkThresh, MinDiamMarks)
find_marks_and_pose (Image, Caltab, CaltabName, StartCamPar, StartThresh, \
DeltaThresh, MinThresh, Alpha, MinContLength, MaxDiamMarks, RCoord, CCoord, StartPose)
// 从标定数据模型中获取基于点的观测数据(49个点的坐标,索引,粗略估计被测校准物体相对于被测相机的姿态)
set_calib_data_observ_points (CalibDataID, 0, 0, I, RCoord, CCoord, 'all', StartPose)
endfor
下面将Halcon中提取目标点的大致原理说一下:
- 首先find_caltab 算子对图像高斯滤波(核大小为SizeGauss),接着阈值分割(与之大小为MarkThresh)将标定板的区域找出来, find_marks_and_pose 算子对区域中的圆进行分割,找到圆的个数,周长,坐标位置等应该和标定板描述文件中的一致,否则会自动调整StartThresh,使得StartThresh按照DeltaThresh步长减小到MinThresh,直到找到准确的圆心。
6.有了所有图像中的圆心就可以标定了
* 返回平均投影误差Errors
calibrate_cameras (CalibDataID, Errors)
7.示例:3d_coordinates 测量世界坐标中的倾斜物体
本地函数: get_measure_positions
(Image : PlateRegion : CalibDataID, PoseIndex : Distance, Phi, RowCenter, ColumnCenter)
** 提取标定板(二值化、计算连通量、利用形状特征选择区域,填充空洞)
* 形状特征有:每个连通区域的孔数;最小包围矩形长度的一半;最小的包围矩形的宽度的一半
threshold (Image, Region, 0, 120)
connection (Region, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, ['holes_num','rect2_len1','rect2_len2'], 'and', [1,120,120], [1,200,200])
fill_up (SelectedRegions, PlateRegion)
*
** 从table(标定板表盘)的边框构造测量矩形:
* 生成区域XLD轮廓
* 计算XLD轮廓的“回归线”的参数
gen_contour_region_xld (PlateRegion, Contours, 'center')
segment_contours_xld (Contours, ContoursSplit, 'lines', 7, 4, 2)
regress_contours_xld (ContoursSplit, RegressContours, 'no', 1)
* 获取两边的垂直边框线(4选2)
select_contours_xld (RegressContours, VerticalContours, 'direction', rad(45), rad(135), -0.5, 0.5)
select_contours_xld (VerticalContours, LongContours, 'length', 150, 500, -0.5, 0.5)
*
** 测量线由table的两个垂直边框线的中心点构成:
* 从对象数组中的选择对象(2选1)
* 获得XLD轮廓所有坐标
select_obj (LongContours, Contour