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')