Halcon学习笔记:3D_coordinates(3D标定)
欢迎有兴趣的朋友一起学习,代码理解注释有问题的可以告诉我,一起讨论,共同进步。
*初始化程序,
dev_close_window() *关闭窗口
dev_open_window( *打开窗口
0, *左上角行坐标位置
0, *左上角列坐标位置
768, *宽度768像素
576, *高度576像素
‘black’, *黑色背景
WindowHandle) *句柄是WindowHandle。
dev_update_off() *关闭画面更新
dev_set_draw(‘margin’) *设置区域的填充模式为边缘
dev_set_line(3) *设置绘图的线宽为3个像素
set_display_font( *设置窗口windowHandle中的字体
windowHandle, *
14, *大小14
‘mono’, *mono字体
‘true’, *粗体
‘false’) *无下划线
CalTabDescrFile := ‘caltab_big.descr’*标定相机,标定板描述文件名
StartCamPar := [ *相机初始参数
0.008, *焦距0.008
0 , *畸变大小0
0.0000086, *像元宽是0.0000086米
0.0000086, *像元高是0.0000086米
384, *相机坐标原点在384像素列,X轴
288, *相机坐标原点在288像素行,Y轴
768, *图片宽768像素
576] *图片高576像素
create_calib_data( *创建标定数据模型CalibDataID
‘calibration_object’, *标定类型
1, *相机个数
1, *标定项目个数
CalibDataID) *标定句柄
set_calib_data_cam_param( *设置相机初始内参
CalibDataID, *标定句柄
0, *相机序号
‘area_scan_division’, *相机模型类型
StartCamPar) *相机参数
set_calib_data_calib_object( *设置相机标定板参数
CalibDataID, *标定句柄
0, *标定板索引
CalTabDescrFile) *标定板文件
NumImages :=10 *图片数量
for I := 1 to NumImages by 1 *循环读取图片并加载到标定模型中
read_image( *读取图片
Image, *输出图片
‘calib/calib-3d-coord-‘ + I$’02d’) *文件路径
dev_display(Image) *显示图片
*要显示的字符串
Message := ‘Find calibration plate in\nall calibration images(‘ + I + ‘/’ + NumImages + ‘)’
disp_message( *显示字符串在窗口中
WindowHandle, *窗口句柄
Message, *字符串
‘window’, *窗口
12, *字符串显示的位置行坐标
12, *字符串显示的位置列坐标
‘black’, *黑色字体
‘true’) *有字体背景颜色
find_calib_object( *找到标定板
Image, *输入图片
CalibDataID, *标定句柄
0, *相机索引
0, *标定板索引
I-1, *校准对象在标定数据模型中位置索引
[ ], *默认参数名
[ ]) *默认参数值
get_calib_data( *获取在校准数据模型中的数据
CalibDataID, *标定句柄
‘camera’, *数据类别
0, *相机索引0
‘init_params’, *参数名
StartCamPar) *参数值
get_calib_data_observ_points( *在校准数据模型中获取 mask‘点‘ 的数据
CalibDataID, *标定句柄
0, *相机索引
0, *标定板索引
I-1, *校准对象在标定数据模型中位置索引
Row, *‘点‘的行坐标
Column, *‘点‘的列坐标
Index, *’点‘在标定板中的索引
Pose) *校准对象相对于相机的估算姿态
get_calib_data_observ_contours( *获取当前图像中标定板的XLD信息
Contours, *XLD轮廓
CalibDataID, *标定句柄
‘caltab’, *数据类别
0, *相机索引
0, *标定板索引
I-1) *校准对象在标定数据模型中位置索引
gen_cross_contour_xld( *为输入的每一个点生成十字形
Cross, *生成的XLD轮廓Cross
Row, *‘点’行坐标
Column, *‘点’列坐标
6, *十字形长度6
0.785398) *十字形旋转弧度
dev_set_color(‘geen’) *设置颜色‘绿’
dev_display(Contours) *显示轮廓Contours
dev_set_color(‘yellow’) *设置颜色‘黄’
dev_display(Cross) *显示轮廓 Cross
endfor
calibrate_cameras( *执行标定
CalibDataID, *标定句柄
Error) *标定误差
get_calib_data( *获取参数
CalibDataID, *标定句柄
‘camera’, *数据类别
0, *相机索引
‘params’, *参数名
CamParam) *参数值
*执行测量
for I := 1 to NumImages by 1
read_image( *读取图片
Image, *输出图片
‘calib/calib-3d-coord-‘ + I$’02d’)*图片路径
get_measure_positions( *获取标定板中心位置以及中心所在宽度线的角度及宽度
Image, *输入图片
PlateRegion, *标定板的外框
CalibDataID, *标定句柄
I, *姿态索引
Distance, *外框水平距离
Phi, *角度
RowCenter, *外框中心点行坐标
ColumnCenter) *外框中心点列坐标
gen_rectangle2_contour_xld( *生成矩形
Rectangle, *生成的矩形
RowCenter, *矩形中心行坐标
ColumnCenter, *矩形中心列坐标
Phi, *矩形的水平方向角度
Distance * 0.52, *矩形半宽度
8) *矩形半高度
gen_measure_rectangle2( *生成测量矩形
RowCenter, *矩形中心行坐标RowCenter
ColumnCenter, *矩形中心列坐标ColumnCenter
Phi, *矩形的水平方向角度Phi
Distance * 0.52, *矩形半宽度
8, *矩形半高度8
768, *测量图片的半宽度768
576, *测量图片的半高度576
‘nearest_neighbor’, *插值类型‘nearest_neighbor’
MeasureHandle) *测量句柄MeasureHandle
measure_pos( *开始测量
Image, *输入图片
MeasureHandle, *测量句柄
1, *高斯滤波参数
40, *边缘强度控制阈值
‘all’, *边界方向
‘all’, *寻点模式
RowEdge, *测到的中心点行坐标
ColumnEdge, *测到的中心点列坐标
Amplitude, *边缘强度值
Distance1) *连续边之间的距离
close_measure(MeasureHandle) *关闭测量矩形句柄
Rows := [ RowEdge[0], RowEdge[|RowEdge| - 1] ] *获取测量点的首尾点行坐标
Columns := [ ColumnEdge[0], ColumnEdge[ |RowEdge| - 1] ] *获取测量点的首尾点列坐标
gen_cross_contour_xld( *生成XLD轮廓
Cross, *生成十字形轮廓
Rows, *轮廓的行坐标
Columns, *轮廓的列坐标
16, *十字形的长度
Phi) *十字形角度
get_calib_data( *获取校准的数据
CalibDataID, *标定句柄
‘calib_obj_pose’, *数据类别,相机位姿
[0, I-1], *数据索引
‘pose’, *数据名
Pose) *数据值
image_points_to_world_plane( *将图像点转换为世界坐标系的平面z = 0
CamParam, *相机参数
Pose, *姿态
Rows, *图像中的点行
Columns, *图像中的点列
‘m’, *比例尺‘m’米
SX, *世界坐标中X
SY) *世界坐标中Y
distance_pp ( * 测量两点距离
SY[0], *第一点Y值
SX[0], *第一点X值
SY[1], *第二点Y值
SX[1], *第二点X值
Width) *输出距离
*显示测量结果
dev_display(Image) *显示图片Image
dev_set_color(‘white’) *设置绘图的颜色为白色
dev_set_line_width(3) *设置绘图的线宽为3像素
dev_display(Rectangle) *显示矩形Rectangle
dev_set_color(‘green’) *设置绘图的颜色为绿色
dev_set_draw(‘fill’) *设置绘制的方式为填充
dev_set_line_width(2) *设置绘图的线宽为2像素
dev_display(Cross) *显示XLD图形Cross
dev_set_draw(‘margin’) *设置绘制方式为边缘
disp_message( *显示测量信息
WindowHandle, *窗口句柄
‘Width = ‘ + (Width * 100)$’8.3f’ + ‘cm’, *信息
‘window’, *窗口
12, *信息显示位置行坐标
12, *信息显示位置列坐标
‘black’, *黑色字体
‘true’) *有字体背景颜色
disp_continue_message( *显示继续信息
WindowHandle, *窗口句柄
‘black’, *黑色字体
‘true’) *有字体背景颜色
stop() *程序暂停
*测量标定板的marks‘点‘ 大小
erosion_circle( *腐蚀图片
PlateRegion, *输入区域
ROI, *输出ROI
17.5) *腐蚀半径
reduce_domain( *裁剪图片
Image, *输入图片
ROI, *要裁剪的区域
ImageReduced) *输出裁剪后的区域
edges_sub_pix( *提取边缘,大于高阈值的一定是边缘
ImageReduced, *输入图像
Edges, *输出边缘
‘canny’, *滤波器
1, *平滑度
20, *低阈值
60) *高阈值
select_contours_xld( *筛选轮廓
Edges, *输入边缘
SelectedEdges, *输出边缘
‘contour_length’, *轮廓特征,轮廓长度
20, *最小值
99999999, *最大值
-0.5, *用不到的参数
0.5) *用不到的参数
fit_ellipse_contour_xld( *生成逼近XLD轮廓线的椭圆
SelectedEdges, *输入轮廓
‘fitzgibbon’, *拟合算法
-1, *用于计算的最大轮廓点个数
2, *一个轮廓的末尾点最大间距为2被认为是闭合
0, *忽略始末点的个数
200, *用于Voss方法的圆形段数
3, *迭代最大次数
2, *裁剪因子
Row, *输出椭圆的中心行坐标
Column, *输出椭圆的中心列坐标
Phi, *输出椭圆主轴方向弧度
Radius1, *长半轴长度
Radius2, *短半轴长度
StartPhi, *起始点方向弧度
EndPhi, *结束点方向弧度
PointOrder) *边界点次序
MeanRadius1 := mean(Radius1) *长半轴平均长度
MeanRadius2 := mean(Radius2) *短半轴平均长度
DevRadius1 := deviation(Radius1) *长半轴标准差
DevRadius2 := deviation(Radius2) *短半轴标准差
contour _to_world_plane_xld( *将图片中轮廓坐标转换到世界坐标系中Z=0
SelectedEdges, *输入轮廓
WorldCircles, *输出轮廓
CamParam, *相机参数
Pose, *输出位姿
‘mm’) *输出单位
fit_ellipse_contour_xld( *拟合椭圆
WorldCircles, *输入轮廓
‘fitzgibbon’, *拟合算法
-1, *用于计算的最大轮廓点个数
2, *一个轮廓的末尾点最大间距为2被认为是闭合
0, *忽略始末点的个数
200, *用于Voss方法的圆形段数
3, *迭代最大次数
2, *裁剪因子
Row, *输出椭圆的中心行坐标
Column, *输出椭圆的中心列坐标
Phi, *输出椭圆主轴方向弧度
RadiusW1, *长半轴长度
RadiusW2, *短半轴长度
StartPhi, *起始点方向弧度
EndPhi, *结束点方向弧度
PointOrder) *边界点次序
MeanRadiusW1 := mean(RadiusW1) *计算平均值
MeanRadiusW2 := mean(RadiusW2) *计算平均值
DevRadiusW1 := deviation(RadiusW1)*计算标准差
DevRadiusW2 := deviation(RadiusW2)*计算标准差
dev_display(Image) *显示图片
dev_set_color(‘yellow’) *设置绘制颜色,黄色
dev_set_line_width(3) *设置绘制宽度
dev_display(SelectedEdges)*显示轮廓
Message[0] :=
' Mean Radius1; Mean Radius2; (Standard deviations [%])'
Message[1] :=
'Image coordinates: '
+ MeanRadius1$'5.2f'
+ 'px; '
+ MeanRadius2$'5.2f'
+ 'px ('
+ (DevRadius1 / MeanRadius1 * 100)$'4.2f'
+ ', '
+ (DevRadius2 / MeanRadius2 * 100)$'4.2f'
+ ')'
Message[2] := 'World coordinates: '
+ (MeanRadiusW1 / 10)$'5.2f'
+ 'cm; '
+ (MeanRadiusW2 / 10)$'5.2f'
+ 'cm ('
+ (DevRadiusW1 / MeanRadiusW1 * 100)$'4.2f'
+ ', '
+ (DevRadiusW2 / MeanRadiusW2 * 100)$'4.2f'
+ ')'
disp_message( *显示消息
WindowHandle, *窗口句柄
Message, *消息
‘window’, *窗口
12, *消息显示位置行坐标
12, *消息显示位置列坐标
‘black’ *黑色字体
‘true’) *有背景颜色
if(I < 10)
disp_continue_message( *显示继续信息
WwindowHandle, *窗口句柄
‘black’, *黑色字体
‘true’) *有背景颜色
stop() *程序暂停
endif
endfor
clear_calib_data(CalibDataID) *清理标定数据模型