因爱智能

halcon学习笔记——(9)摄像机标定

1.read_cam_par( : : CamParFile : CameraParam) 
从文件夹中读取相机的内参数。 
2.disp_caltab( : : WindowHandle, CalTabDescrFile, CameraParam, CaltabPose, ScaleFac : ) 
利用相机内外参数,把标定板模型投影到图像平面,显示标定点和连接线,X,Y轴也被显示出来。 
3.vector_to_pose( : : WorldX, WorldY, WorldZ, ImageRow, ImageColumn, CameraParam, Method, QualityType : Pose, Quality) 
计算世界坐标和图像坐标之间关系的绝对位姿参数。其中世界坐标至少选择不在同一条直线上的三个点。 
世界坐标上的点如果在一个平面上,应该选择'planar_analytic' 作为Method的参数。输出位姿和位姿质量。 
4.write_pose( : : Pose, PoseFile : ) 
把位姿写入TXT文件。 
5.get_mbutton( : : WindowHandle : Row, Column, Button) 
返回鼠标点击的图像点像素坐标,以及鼠标按钮值,左键0,中间键2,右键4. 
6.image_points_to_world_plane( : : CameraParam, WorldPose, Rows, Cols, Scale : X, Y) 
把图像坐标转化成Z=0平面的世界坐标,输出为世界坐标的X,Y 
7.pose_to_hom_mat3d( : : Pose : HomMat3D) 
把3D位姿转化成齐次变换矩阵。 
8.affine_trans_point_3d( : : HomMat3D, Px, Py, Pz : Qx, Qy, Qz) 
进行两个坐标系之间的3D坐标的仿射变换。 
       / Qx \             / Px \ 
| Qy | = HomMat3D * | Py | 
| Qz | | Pz | 
\ 1 / \ 1 / 
9.project_3d_point( : : X, Y, Z, CameraParam : Row, Column) 
把3D点映射到图像坐标系,返回图像坐标系中该点的行列坐标。 
  
10.smallest_rectangle2(Regions : : : Row, Column, Phi, Length1, Length2) 
返回包含一个区域的最小环绕矩形。 
11.gen_measure_rectangle2( : : Row, Column, Phi, Length1, Length2, Width, Height, Interpolation : MeasureHandle) 
返回和矩形边垂直的边缘。 
12.measure_pairs(Image : : MeasureHandle, Sigma, Threshold, Transition, Select : RowEdgeFirst, ColumnEdgeFirst, AmplitudeFirst, RowEdgeSecond, ColumnEdgeSecond, AmplitudeSecond, IntraDistance, InterDistance) 
抽取和矩形边垂直的边缘对。返回各测量对之间的距离。 
13.close_measure( : : MeasureHandle : ) 
删除测量句柄。 
14.gen_region_polygon_filled( : Region : Rows, Columns : ) 
创建多边形填充区域,输出为一个区域。 
15.gen_region_polygon_filled( : Region : Rows, Columns : ) 
提取直线极其宽度,输出为XLD形式数组。 
16.hom_mat3d_compose( : : HomMat3DLeft, HomMat3DRight : HomMat3DCompose) 
输出两个齐次矩阵的乘积。 
17.hom_mat3d_translate_local( : : HomMat3D, Tx, Ty, Tz : HomMat3DTranslate) 
相对于新坐标系统,增加一个平移量到齐次矩阵HomMat3D中,输出为新的齐次矩阵。 
18.hom_mat3d_rotate_local( : : HomMat3D, Phi, Axis : HomMat3DRotate) 
相对于新坐标系统,增加一个绕着某个坐标轴的旋量到齐次矩阵HomMat3D中,输出为新的齐次矩阵。 
17.contour_to_world_plane_xld(Contours : ContoursTrans : CameraParam, WorldPose, Scale : ) 
转换XLD轮廓进入Z=0的世界坐标平面,输出形式为xld_cont(-array) → object 
18.get_contour_xld(Contour : : : Row, Col) 
返回轮廓点的行列坐标。 
19.tuple_mean( : : Tuple : Mean) 
返回数组的平均值 
20.map_image(Image, Map : ImageMapped : : ) 
对图像进行校正,输出为校正后的图像。

附:摄像机校正和利用校正后的结果进行测量以及图像校正的程序段:

1: * Attention: 2: * This program reads the interior camera parameters from the file 3: * 'camera_parameters.dat', which, e.g., could be generated by the program 4: * 'camera_calibration_interior.hdev' 5: * 6: ImgPath := '3d_machine_vision/calib/' 7: dev_close_window () 8: dev_open_window (0, 0, 652, 494, 'black', WindowHandle) 9: dev_update_off () 10: dev_set_draw ('margin') 11: dev_set_line_width (1) 12: set_display_font (WindowHandle, 14, 'courier', 'true', 'false') 13: * Read the interior camera parameters from file 14: read_cam_par ('camera_parameters.dat', CamParam) 15: * 16: * Determine the exterior camera parameters and world coodinates from image points 17: * 18: * The exterior camera parameters can be determined from an image, where the 19: * calibration plate is positioned directly on the measurement plane 20: read_image (Image, ImgPath+'calib_11') 21: dev_display (Image) 22: * parameter settings for find_caltab and find_marks_and_pose 23: SizeGauss := 3 24: MarkThresh := 200 25: MinDiamMarks := 10 26: StartThresh := 128 27: DeltaThresh := 10 28: MinThresh := 18 29: Alpha := 0.9 30: MinContLength := 15 31: MaxDiamMarks := 100 32: CaltabName := 'caltab_30mm.descr' 33: find_caltab (Image, Caltab, CaltabName, SizeGauss, MarkThresh, MinDiamMarks) 34: dev_set_color ('green') 35: dev_display (Caltab) 36: * Here, the final camera parameters are already known and can be used instead of the starting values 37: * used in the program 'camera_calibration_interior.hdev' 38: find_marks_and_pose (Image, Caltab, CaltabName, CamParam, StartThresh, DeltaThresh, MinThresh, Alpha, MinContLength, MaxDiamMarks, RCoord, CCoord, PoseForCalibrationPlate) 39: dev_set_color ('red') 40: disp_caltab (WindowHandle, CaltabName, CamParam, PoseForCalibrationPlate, 1) 41: dev_set_line_width (3) 42: disp_circle (WindowHandle, RCoord, CCoord, gen_tuple_const(|RCoord|,1.5)) 43: * caltab_points (CaltabName, X, Y, Z) 44: * camera_calibration (X, Y, Z, RCoord, CCoord, CamParam, InitialPoseForCalibrationPlate, 'pose', CamParamUnchanged, FinalPoseFromCalibrationPlate, Errors) 45: * To take the thickness of the calibration plate into account, the z-value 46: * of the origin given by the camera pose has to be translated by the 47: * thickness of the calibration plate. 48: * Deactivate the following line if you do not want to add the correction. 49: set_origin_pose (PoseForCalibrationPlate, 0, 0, 0.00075, PoseForCalibrationPlate) 50: disp_continue_message (WindowHandle, 'black', 'true') 51: stop () 52: * Alternatively, the exterior camera parameters can be determined from 53: * at least three point correspondances between the WCS and the pixel coordinate system 54: read_image (Image, ImgPath+'caliper_01') 55: dev_display (Image) 56: * Set the world coordinates of three points on the rule 57: X := [0,50,100,80] 58: Y := [5,0,5,0] 59: Z := [0,0,0,0] 60: * Set the respective image plane coordinates of the three points 61: RCoord := [414,227,85,128] 62: CCoord := [119,318,550,448] 63: * 64: disp_cross (WindowHandle, RCoord, CCoord, 6, 0) 65: * create_pose (-50, 25, 400, 0, 0, -30, 'Rp+T', 'gba', 'point', InitialPose) 66: vector_to_pose (X, Y, Z, RCoord, CCoord, CamParam, 'iterative', 'error', FinalPose, Errors) 67: * camera_calibration (X, Y, Z, RCoord, CCoord, CamParam, InitialPose, 'pose', CamParamUnchanged, FinalPose, Errors) 68: write_pose (FinalPose, 'pose_from_three_points.dat') 69: * Now, transform a point measured interactively into the WCS 70: dev_update_window ('on') 71: dev_display (Image) 72: while (1) 73: disp_message (WindowHandle, 'Measure one point: left mouse button', 'window', 12, 12, 'red', 'false') 74: disp_message (WindowHandle, 'Exit measure mode: right mouse button', 'window', 36, 12, 'red', 'false') 75: get_mbutton (WindowHandle, Row, Column, Button) 76: if (Button = 4) 77: break 78: endif 79: dev_display (Image) 80: dev_set_color ('green') 81: disp_cross (WindowHandle, Row, Column, 6, 0) 82: image_points_to_world_plane (CamParam, FinalPose, Row, Column, 1, X1, Y1) 83: disp_message (WindowHandle, 'X = '+X1, 'window', 320, 400, 'red', 'false') 84: disp_message (WindowHandle, 'Y = '+Y1, 'window', 340, 400, 'red', 'false') 85: endwhile 86: * Apply the measure tool and transform the resulting point coordinates 87: * into the WCS 88: dev_set_color ('red') 89: dev_display (Image) 90: * Set the world coordinates of four points defining a ROI for the measure tool 91: ROI_X_WCS := [-2,-2,112,112] 92: ROI_Y_WCS := [0,0.5,0.5,0] 93: ROI_Z_WCS := [0,0,0,0] 94: * Determine the transformation matrix from the WCS into the CCS 95: pose_to_hom_mat3d (FinalPose, CCS_HomMat_WCS) 96: * Transform the point coordintes into the image coordinate system 97: affine_trans_point_3d (CCS_HomMat_WCS, ROI_X_WCS, ROI_Y_WCS, ROI_Z_WCS, CCS_RectangleX, CCS_RectangleY, CCS_RectangleZ) 98: project_3d_point (CCS_RectangleX, CCS_RectangleY, CCS_RectangleZ, CamParam, RectangleRow, RectangleCol) 99: gen_region_polygon_filled (ROI, RectangleRow, RectangleCol) 100: smallest_rectangle2 (ROI, RowCenterROI, ColCenterROI, PhiROI, Length1ROI, Length2ROI) 101: * Create a measure 102: gen_measure_rectangle2 (RowCenterROI, ColCenterROI, PhiROI, Length1ROI, Length2ROI, 652, 494, 'bilinear', MeasureHandle) 103: measure_pairs (Image, MeasureHandle, 0.4, 5, 'all_strongest', 'all', RowEdgeFirst, ColumnEdgeFirst, AmplitudeFirst, RowEdgeSecond, ColumnEdgeSecond, AmplitudeSecond, IntraDistance, InterDistance) 104: close_measure (MeasureHandle) 105: dev_display (Image) 106: disp_message (WindowHandle, 'Measuring the position of the pitch lines', 'window', 450, 25, 'red', 'false') 107: dev_set_color ('green') 108: RowPitchLine := (RowEdgeFirst+RowEdgeSecond)/2.0 109: ColPitchLine := (ColumnEdgeFirst+ColumnEdgeSecond)/2.0 110: disp_cross (WindowHandle, RowPitchLine, ColPitchLine, 6, 0) 111: image_points_to_world_plane (CamParam, FinalPose, RowPitchLine, ColPitchLine, 1, X1, Y1) 112: for i := 1 to |X1| by 1 113: set_tposition (WindowHandle, RowEdgeFirst[i-1]+5, ColumnEdgeFirst[i-1]-20) 114: if (i=|X1|) 115: set_tposition (WindowHandle, RowEdgeFirst[i-1], ColumnEdgeFirst[i-2]) 116: endif 117: write_string (WindowHandle, X1[i-1]$'.3f'+'mm') 118: endfor 119: disp_continue_message (WindowHandle, 'black', 'true') 120: stop () 121: dev_display (Image) 122: * Apply a line extraction and transform the resulting xld contours 123: * into the WCS 124: * Set the world coordinates of four points defining a ROI 125: ROI_X_WCS := [11,11,13,13] 126: ROI_Y_WCS := [4,6,6,4] 127: ROI_Z_WCS := [0,0,0,0] 128: * Transform the point coordinates into the image coordinate system 129: affine_trans_point_3d (CCS_HomMat_WCS, ROI_X_WCS, ROI_Y_WCS, ROI_Z_WCS, CCS_RectangleX, CCS_RectangleY, CCS_RectangleZ) 130: project_3d_point (CCS_RectangleX, CCS_RectangleY, CCS_RectangleZ, CamParam, RectangleRow, RectangleCol) 131: * Visualize the square in the original image 132: disp_polygon (WindowHandle, [RectangleRow,RectangleRow[0]], [RectangleCol,RectangleCol[0]]) 133: dev_display (Image) 134: * create the ROI 135: gen_region_polygon_filled (ROI, RectangleRow, RectangleCol) 136: reduce_domain (Image, ROI, ImageReduced) 137: * Extract the lines 138: lines_gauss (ImageReduced, Lines, 1, 3, 8, 'dark', 'true', 'bar-shaped', 'true') 139: * Adapt the pose of the measurement plane to the tilted plane of the vernier 140: RelPose := [0,3.2,0,-14,0,0,0] 141: pose_to_hom_mat3d (FinalPose, HomMat3D) 142: pose_to_hom_mat3d (RelPose, HomMat3DRel) 143: hom_mat3d_compose (HomMat3D, HomMat3DRel, HomMat3DAdapted) 144: * Alternatively, the adaption can be done using the operators 145: * hom_mat3d_translate_local and hom_mat3d_rotate_local 146: * as shown in the following to lines 147: hom_mat3d_translate_local (HomMat3D, 0, 3.2, 0, HomMat3DTranslate) 148: hom_mat3d_rotate_local (HomMat3DTranslate, rad(-14), 'x', HomMat3DAdapted) 149: hom_mat3d_to_pose (HomMat3DAdapted, PoseAdapted) 150: * Transform the xld contour to the WCS using the adapted pose 151: contour_to_world_plane_xld (Lines, ContoursTrans, CamParam, PoseAdapted, 1) 152: get_contour_xld (ContoursTrans, YOfContour, XOfContour) 153: tuple_mean (XOfContour, MeterReading) 154: dev_display (Lines) 155: disp_message (WindowHandle, 'Meter reading: '+MeterReading$'.3f'+'mm', 'window', 400, 180, 'green', 'false') 156: disp_continue_message (WindowHandle, 'black', 'true') 157: stop () 158: dev_close_inspect_ctrl (YOfContour) 159: dev_close_inspect_ctrl (XOfContour) 160: * Now, transform the whole image 161: WidthMappedImage := 652 162: HeightMappedImage := 494 163: dev_display (Image) 164: * First, determine the scale for the mapping 165: * (here, the scale is determined such that in the 166: * surroundings of the points P0 and P1, the image scale of the 167: * mapped image is similar to the image scale of the original image) 168: distance_pp (X[0], Y[0], X[1], Y[1], DistP0P1WCS) 169: distance_pp (RCoord[0], CCoord[0], RCoord[1], CCoord[1], DistP0P1PCS) 170: Scale := DistP0P1WCS/DistP0P1PCS 171: * Then, determine the parameter settings for set_origin_pose such 172: * that the point given via get_mbutton will be in the center of the 173: * mapped image 174: dev_display (Image) 175: disp_message (WindowHandle, 'Define the center of the mapped image', 'window', 12, 12, 'red', 'false') 176: get_mbutton (WindowHandle, CenterRow, CenterColumn, Button1) 177: image_points_to_world_plane (CamParam, FinalPose, CenterRow, CenterColumn, 1, CenterX, CenterY) 178: set_origin_pose (FinalPose, CenterX-Scale*WidthMappedImage/2.0, CenterY-Scale*HeightMappedImage/2.0, 0, PoseNewOrigin) 179: gen_image_to_world_plane_map (Map, CamParam, PoseNewOrigin, 652, 494, WidthMappedImage, HeightMappedImage, Scale, 'bilinear') 180: map_image (Image, Map, ImageMapped) 181: dev_clear_window () 182: dev_display (ImageMapped) 183: * In case, only one image has to be mapped, the operator 184: * image_to_world_plane can be used instead of the operators 185: * gen_image_to_world_plane_map together with map_image. 186: image_to_world_plane (Image, ImageMapped, CamParam, PoseNewOrigin, WidthMappedImage, HeightMappedImage, Scale, 'bilinear')

 

原文来自:大疯熊和小兔子的幸福生活

作者:韩兆新

出处:http://hanzhaoxin.cnblogs.com/

评论