赞
踩
// 关闭当前的图像窗口 dev_close_window () // 以指定的位置、尺寸、背景颜色打开一个新的窗口 dev_open_window (0, 0, 768, 576, 'black', WindowHandle) // 取消所有自动更新 dev_update_off () // 设置绘制模式 dev_set_draw ('margin') // 设置显示线宽 dev_set_line_width (3) // 设置显示字体 set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
// 指定标定板描述文件 CalTabDescrFile := 'caltab_big.descr' /* 设置初始相机内参 * 参数按位置顺序依次为: * 镜头焦距 * 径向扭曲系数 * 像元水平尺寸(单位:米) * 像元垂直尺寸(单位:米) * 图像坐标系下的主点列坐标(单位:像素) * 图像坐标系下的主点行坐标(单位:像素) * 图像宽度(单位:像素) * 图像高度(单位:像素) */ gen_cam_par_area_scan_division (0.008, 0, 0.0000086, 0.0000086, 384, 288, 768, 576, StartCamPar) /* 创建相机标定模型 * 参数按位置顺序依次为: * 标定的类型 * 同时标定的相机数量 * 标定板对象的数量 * 输出的标定模型句柄 */ create_calib_data ('calibration_object', 1, 1, CalibDataID) /* 设置标定模型的初始相机内参 * 参数按位置顺序依次为: * 标定模型句柄 * 相机索引 * 相机类型 * 相机内参 */ set_calib_data_cam_param (CalibDataID, 0, [], 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, [], []) /* 获取初始标定参数 * 参数按位置顺序依次为: * 标定句柄 * 标定数据类型,'calib_obj', 'calib_obj_pose', 'camera', 'model', 'tool' * 索引 * 数据名 * 返回数据值 */ get_calib_data (CalibDataID, 'camera', 0, 'init_params', StartCamPar) /* 获取标志点的图像坐标与姿态 * 参数按位置顺序依次为: * 标定句柄 * 相机索引 * 标定对象索引 * 标定对象姿态索引 * 标志点行坐标 * 标志点列坐标 * 标志点索引号 * 标定对象相对于相机坐标系的姿态 */ get_calib_data_observ_points (CalibDataID, 0, 0, I - 1, Row, Column, Index, Pose) /* 获取标定对象边界轮廓 * 参数按位置顺序依次为: * 输出轮廓 * 标定句柄 * 轮廓名,'caltab', 'last_caltab', 'marks' * 相机索引 * 标定对象索引 * 标定对象姿态索引 */ get_calib_data_observ_contours (Contours, CalibDataID, 'caltab', 0, 0, I - 1) // 创建十字标识 gen_cross_contour_xld (Cross, Row, Column, 6, 0.785398) // 设置颜色 dev_set_color ('green') // 显示轮廓 dev_display (Contours) // 设置颜色 dev_set_color ('yellow') // 显示十字标识 dev_display (Cross) endfor // 显示提示信息 disp_continue_message (WindowHandle, 'black', 'true') stop () // 执行标定 calibrate_cameras (CalibDataID, Error) // 获取标定后的相机参 get_calib_data (CalibDataID, 'camera', 0, 'params', CamParam)
为了计算边距或标志点的半径,都需要对图像进行预处理。因此,先介绍预处理函数。
/* 函数的参数依次为: * Image : (IN) 标定对象图像 * PlateRegion : (OUT) 标定对象区域 * CalibDataID : (IN) 标定句柄 * PoseIndex : (IN) 标定姿态索引 * Distance : (OUT) 边距的粗略距离 * Phi : (OUT) 标定对象的旋转角度 * RowCenter : (OUT) 标定板中心行坐标 * ColumnCenter: (OUT) 标定板中心列坐标 */ // 固定阈值二值化 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)
/* 根据区域的边界生成轮廓 * 第三个参数为提取边界的模式,有以下值: * center : 边界像素的中心点连接成的轮廓 * border : 边界像素的外轮廓 * border_holes : 除了边界像素的被提取,孔边界也被提取 */ gen_contour_region_xld (PlateRegion, Contours, 'center') /* 将轮廓分割成直线段和圆弧段或椭圆弧段 * 参数按位置顺序依次为: * 输入轮廓 * 分割后轮廓 * 分割模式,'lines', 'lines_circles', 'lines_ellipses' * 平滑轮廓使用的点数 * 第一次迭代使用弧替代直线段的最大距离 * 第二次迭代使用弧替代直线段的最大距离 */ segment_contours_xld (Contours, ContoursSplit, 'lines', 7, 4, 2) // 计算回归线 regress_contours_xld (ContoursSplit, RegressContours, 'no', 1) // 轮廓选择 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) // 选择第一个垂直边缘 select_obj (LongContours, Contour, 1) // 获取轮廓点 get_contour_xld (Contour, Rows, Columns) // 获取起始点 RowBegin1 := Rows[0] ColBegin1 := Columns[0] // 获取终止点 RowEnd1 := Rows[|Rows| - 1] ColEnd1 := Columns[|Columns| - 1] // 选择第二个垂直边缘 select_obj (LongContours, Contour, 2) // 获取轮廓点 get_contour_xld (Contour, Rows, Columns) // 获取起始点 RowBegin2 := Rows[0] ColBegin2 := Columns[0] // 获取终止点 RowEnd2 := Rows[|Rows| - 1] ColEnd2 := Columns[|Columns| - 1] // 获取标志点的中心坐标 get_calib_data_observ_points (CalibDataID, 0, 0, PoseIndex - 1, Row, Column, PoseIndex, _Pose) // 选取过中心且垂直于提取垂直边缘的标志点中心 Row1 := Row[find(PoseIndex,21)] Row2 := Row[find(PoseIndex,27)] Column1 := Column[find(PoseIndex,21)] Column2 := Column[find(PoseIndex,27)] // 显示直线段,并计算焦点 dev_get_window (WindowHandle) disp_line (WindowHandle, Row1, Column1, Row2, Column2) disp_line (WindowHandle, RowBegin1, ColBegin1, RowEnd1, ColEnd1) intersection_lines (Row1, Column1, Row2, Column2, RowBegin1, ColBegin1, RowEnd1, ColEnd1, RowA, ColA, IsOverlapping) // 显示直线段,并计算焦点 dev_get_window (WindowHandle) disp_line (WindowHandle, Row1, Column1, Row2, Column2) disp_line (WindowHandle, RowBegin2, ColBegin2, RowEnd2, ColEnd2) intersection_lines (Row1, Column1, Row2, Column2, RowBegin2, ColBegin2, RowEnd2, ColEnd2, RowB, ColB, IsOverlapping) // 计算距离 distance_pp (RowA, ColA, RowB, ColB, Distance) // 计算角度 line_orientation (RowA, ColA, RowB, ColB, Phi) // 计算中心坐标 RowCenter := (RowA + RowB) / 2 ColumnCenter := (ColA + ColB) / 2
// 读取图像 read_image (Image, 'calib/calib-3d-coord-01') // 获取测量参数 get_measure_positions (Image, PlateRegion, CalibDataID, 0, Distance, Phi, RowCenter, ColumnCenter) // 生成测量矩形,用于显示 gen_rectangle2_contour_xld (Rectangle, RowCenter, ColumnCenter, Phi, Distance * 0.52, 8) // 矩形区域测量 gen_measure_rectangle2 (RowCenter, ColumnCenter, Phi, Distance * 0.52, 8, 768, 576, 'nearest_neighbor', MeasureHandle) // 执行测量 measure_pos (Image, MeasureHandle, 1, 40, 'all', 'all', RowEdge, ColumnEdge, Amplitude, Distance1) // 显示测量点的位置 Rows := [RowEdge[0],RowEdge[|RowEdge| - 1]] Columns := [ColumnEdge[0],ColumnEdge[|RowEdge| - 1]] gen_cross_contour_xld (Cross, Rows, Columns, 16, Phi) // 获取标定板的姿态 get_calib_data (CalibDataID, 'calib_obj_pose', [0,0], 'pose', Pose) // 图像坐标系到世界坐标系的映射 image_points_to_world_plane (CamParam, Pose, Rows, Columns, 'm', SX, SY) // 世界坐标系的距离季孙 distance_pp (SY[0], SX[0], SY[1], SX[1], Width) // 显示测量结果 dev_display (Image) dev_set_color ('white') dev_set_line_width (3) dev_display (Rectangle) dev_set_color ('green') dev_set_draw ('fill') dev_set_line_width (2) dev_display (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')
// 腐蚀区域 erosion_circle (PlateRegion, 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 (SelectedEdges, 'fitzgibbon', -1, 2, 0, 200, 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 (SelectedEdges, WorldCircles, CamParam, Pose, 'mm') // 世界坐标系下的边缘拟合 fit_ellipse_contour_xld (WorldCircles, 'fitzgibbon', -1, 2, 0, 200, 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 := 'Measured dimensions of the ellipses' 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')
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。