1.图像坐标系,摄像机坐标系,世界坐标系
勇哥说明一下:
图像坐标系就是相机感觉芯片上的坐标系。
摄像机坐标系就是镜头表面上的坐标系。
世界坐标系就是摄像机看到内容的坐标系。
2. 摄像机内部参数:[Focus,Kappa,Sx,Sy,Cx,Cy,Whith,Height]
面阵相机(division模式):
Focus(焦距):远焦镜头镜头焦距的长度
Kappa:扭曲系数(畸变)
Sx,Sy:像素大小
Cx,Cy:图像中心点坐标
Whith,Height:图像的宽高
面阵相机(polynomia模式):
Focus(焦距):远焦镜头镜头焦距的长度
K1, K2, K3, P1,P2:扭曲系数
Sx,Sy:像素大小
Cx,Cy:图像中心点坐标
Whith,Height:图像的宽高
Baler相机资料介绍
https://www.baslerweb.com/cn/products/cameras/area-scan-cameras/ace/aca640-90gc/
2. 摄像机外部参数:世界坐标系下摄像机的位姿,描述摄像机坐标系转换为世界坐标系的转换关系,这个转换关系包括了旋转和平移信息,又成为位姿,位姿可以表示为:[X轴平移,Y轴平移,Z轴平移,X轴旋转,Y轴旋转,Z轴旋转],摄像机外部参数通过摄像机拍摄标定板获取的;
注意:外部参数跟摄像机的位姿说的是同一个东西。
(1)获取外参的例子
dev_close_window () dev_update_off () dev_set_draw ('margin') read_image (Image, 'scratch/scratch_perspective') get_image_pointer1 (Image, Pointer, Type, Width, Height) dev_open_window (0, 0, Width, Height, 'black', WindowHandle1) set_display_font (WindowHandle1, 14, 'mono', 'true', 'false') dev_display (Image) disp_continue_message (WindowHandle1, 'black', 'true') stop () * * step: calibrate the camera * CaltabName := 'caltab_30mm.descr' * make sure that the file 'CaltabDescrName' is in the current directory, * the HALCONROOT/calib directory, or use an absolut path *StartCamPar := [0.012,0,0.0000055,0.0000055,Width/2,Height/2,Width,Height] StartCamPar := [0.0184898,-548.002,8.33409e-006,8.3e-006,275.291,255.374,640,480] create_calib_data ('calibration_object', 1, 1, CalibDataID) set_calib_data_cam_param (CalibDataID, 0, 'area_scan_division', StartCamPar) set_calib_data_calib_object (CalibDataID, 0, CaltabName) NumImages := 12 for i := 1 to NumImages by 1 read_image (Image, 'scratch/scratch_calib_'+i$'02d') dev_display (Image) find_caltab (Image, Caltab, CaltabName, 3, 112, 5) dev_set_color ('green') dev_display (Caltab) find_marks_and_pose (Image, Caltab, CaltabName, StartCamPar, 128, 10, 18, 0.9, 15, 100, RCoord, CCoord, StartPose) dev_set_color ('red') disp_circle (WindowHandle1, RCoord, CCoord, gen_tuple_const(|RCoord|,2.5)) dev_set_part (0, 0, Height-1, Width-1) set_calib_data_observ_points (CalibDataID, 0, 0, i, RCoord, CCoord, 'all', StartPose) endfor dev_update_time ('on') disp_continue_message (WindowHandle1, 'black', 'true') stop () calibrate_cameras (CalibDataID, Error) get_calib_data (CalibDataID, 'camera', 0, 'params', CamParam) get_calib_data (CalibDataID, 'calib_obj_pose', [0,1], 'pose', PoseCalib) write_pose (PoseCalib, 'Externalcamera_parameters.dat')
(2)获取内参例子一
* This example compares the calibration results obtained * for the camera models 'division' and 'polynomial'. * A sequence of calibration images was acquired with a camera * that has a lens with strong radial distortions. Multiple * calibrations of the camera are performed by appending a new * image from the sequence to the calibration data for each * successive calibration turn. * * dev_update_off () dev_close_window () * read_image (Image, 'calib/calib_distorted_01') get_image_size (Image, Width, Height) dev_open_window_fit_image (Image, 0, 0, 400, 400, WindowHandle) get_window_extents (WindowHandle, MainR, MainC, MainWidth, MainHeight) set_display_font (WindowHandle, 14, 'mono', 'true', 'false') dev_set_line_width (1) dev_set_draw ('margin') * StartCamParPoly := [0.005,0,0,0,0,0,9.3e-6,9.3e-6,Width * 0.5,Height * 0.5,Width,Height] StartCamParDiv := [0.005,0,9.3e-6,9.3e-6,Width * 0.5,Height * 0.5,Width,Height] * dev_set_window (WindowHandle) dev_display (Image) disp_message (WindowHandle, 'Determine the marks and pose of\nthe calibration plate for the camera\nmodels \'division\' and \'polynomial\'', 'window', 12, 12, 'black', 'true') disp_continue_message (WindowHandle, 'black', 'true') stop () * create_calib_data ('calibration_object', 1, 1, DivCalibDataID) set_calib_data_cam_param (DivCalibDataID, 0, 'area_scan_division', StartCamParDiv) set_calib_data_calib_object (DivCalibDataID, 0, 'caltab_100mm.descr') * create_calib_data ('calibration_object', 1, 1, PolyCalibDataID) set_calib_data_cam_param (PolyCalibDataID, 0, 'area_scan_polynomial', StartCamParPoly) set_calib_data_calib_object (PolyCalibDataID, 0, 'caltab_100mm.descr') * * Determine marks and pose of the calibration plate to perform the calibration * set_calib_model_params_specific (DivCalibDataID, 'camera', 0, 'excluded_params', 'pose') * set_calib_model_params_specific (PolyCalibDataID, 'camera', 0, 'excluded_params', 'pose') StatFDiv := [] StatKappaDiv := [] StatSxDiv := [] StatCyDiv := [] StatFPoly := [] StatK1Poly := [] StatSxPoly := [] StatCyPoly := [] NumImgs := 69 NumImgsSkip := 13 ImgsBaseFN := 'calib/calib_distorted_' * Choose, in which order the calibration images * shall be used. You can select between an ascending * order: Indices := [1:NumImgs] * and a random order, which is selected by * uncommenting the following line: * Indices := [34,16,52,29,63,65,45,14,10,3,38,18,49,36,59,6,21,43,50,47,1,11,26,44,13,28,66,68,48,54,40,67,2,55,30,17,69,64,56,60,23,5,58,27,20,57,9,31,25,46,4,53,61,39,37,32,7,15,22,41,19,51,12,42,62,33,8,35,24] * * If you use the images in ascending order, the calibration * first uses the images with calibration plates that are not * tilted and then the images with the tilted calibration plates. * Within the graphs you see that the standard deviation * is significantly improved after adding the tilted * calibration plates. * If you use the images in random order, the standard deviation * is also improved, but at an earlier stage of the calibration. * Note that the random sequence has been created with the * following line and has been hard coded to get repeatable * results: * Indices := sort_index(rand(NumImgs)) + 1 * MaxDF := 0 MaxDSx := 0 MaxDSy := 0 for K := 1 to NumImgs by 1 I := Indices[K - 1] read_image (Image, ImgsBaseFN + I$'02') find_calib_object (Image, DivCalibDataID, 0, 0, K, [], []) find_calib_object (Image, PolyCalibDataID, 0, 0, K, [], []) * * * dev_display (Image) dev_set_color ('green') get_calib_data_observ_points (DivCalibDataID, 0, 0, K, Row, Column, Index, StartPose) disp_caltab (WindowHandle, 'caltab_100mm.descr', StartCamParDiv, StartPose, 1) * dev_set_color ('magenta') get_calib_data_observ_points (PolyCalibDataID, 0, 0, K, Row, Column, Index, StartPose) disp_caltab (WindowHandle, 'caltab_100mm.descr', StartCamParPoly, StartPose, 1) disp_message (WindowHandle, 'Extracting calibration features', 'window', -1, -1, 'black', 'true') * * Perform calibration * (if a minimum number of images has been processed) if (K > NumImgsSkip) calibrate_cameras (DivCalibDataID, ErrorsDiv) calibrate_cameras (PolyCalibDataID, ErrorsPoly) get_calib_data (DivCalibDataID, 'camera', 0, 'params', CamParamDiv) get_calib_data (PolyCalibDataID, 'camera', 0, 'params', CamParamPoly) get_calib_data (DivCalibDataID, 'camera', 0, 'params_deviations', DeviationsDiv) get_calib_data (PolyCalibDataID, 'camera', 0, 'params_deviations', DeviationsPoly) * StatFDiv := [StatFDiv,CamParamDiv[0],DeviationsDiv[0]] StatKappaDiv := [StatKappaDiv,CamParamDiv[1],DeviationsDiv[1]] StatSxDiv := [StatSxDiv,CamParamDiv[2],DeviationsDiv[2]] StatCyDiv := [StatCyDiv,CamParamDiv[5],DeviationsDiv[5]] StatFPoly := [StatFPoly,CamParamPoly[0],DeviationsPoly[0]] StatK1Poly := [StatK1Poly,CamParamPoly[1],DeviationsPoly[1]] StatSxPoly := [StatSxPoly,CamParamPoly[6],DeviationsPoly[6]] StatCyPoly := [StatCyPoly,CamParamPoly[9],DeviationsPoly[9]] * MaxDF := max([MaxDF,DeviationsDiv[0],DeviationsPoly[0]]) MaxDSx := max([MaxDSx,DeviationsDiv[2],DeviationsPoly[6]]) MaxDSy := max([MaxDSy,DeviationsDiv[3],DeviationsPoly[7]]) endif endfor disp_message (WindowHandle, ['Extraction completed!','Proceed to the inspection of the','standard deviations'], 'window', -1, -1, 'black', 'true') disp_continue_message (WindowHandle, 'black', 'true') stop () * clear_calib_data (PolyCalibDataID) clear_calib_data (DivCalibDataID) * WinWidth := 600 WinHeight := 300 dev_open_window (0, MainWidth + 13, WinWidth, WinHeight, 'black', WindowHandleDiv) dev_open_window (MainHeight + 62, 0, MainWidth, 2 * WinHeight - MainHeight, 'black', WindowlHandleCmp) dev_open_window (WinHeight + 62, MainWidth + 13, WinWidth, WinHeight, 'black', WindowHandlePoly) * * Inspect focal length ImgNumRange := [NumImgsSkip + 1,NumImgs] plot_stats_graph (StatFDiv, WindowHandleDiv, 'Focal length - Division', [], true, ['Focal length','Std. deviation'], ImgNumRange, PlotStartC, PlotEndC) plot_stats_graph (StatFPoly, WindowHandlePoly, 'Focal length - Polynomial', [], true, ['Focal length','Std. deviation'], ImgNumRange, PlotStartC, PlotEndC) plot_compare_graph (StatFPoly, StatFDiv, WindowlHandleCmp, ['Standard deviation - Focal length','(comparison)'], ['polynomial','divisional'], ImgNumRange) inspect_images (WindowHandle, WindowHandleDiv, NumImgs, NumImgsSkip, PlotStartC, PlotEndC, Indices, ImgsBaseFN, 'Focal length - Division') wait_seconds (.5) * Inspect radial distortion parameters (Kappa and K1) plot_stats_graph (StatKappaDiv, WindowHandleDiv, 'Kappa - Division', [], false, ['kappa','std. deviation'], ImgNumRange, PlotStartC, PlotEndC) plot_stats_graph (StatK1Poly, WindowHandlePoly, 'K1 - Polynomial', [], false, ['K1','std. deviation'], ImgNumRange, PlotStartC, PlotEndC) dev_set_window (WindowlHandleCmp) dev_clear_window () disp_message (WindowlHandleCmp, '[comparison not available]', 'window', 130, 120, 'white', 'false') inspect_images (WindowHandle, WindowHandleDiv, NumImgs, NumImgsSkip, PlotStartC, PlotEndC, Indices, ImgsBaseFN, 'Kappa - Division') wait_seconds (.5) * Inspect Sx plot_stats_graph (StatSxDiv, WindowHandleDiv, 'Sx - Division', [], true, ['sx','std. deviation'], ImgNumRange, PlotStartC, PlotEndC) plot_stats_graph (StatSxPoly, WindowHandlePoly, 'Sx - Polynomial', [], true, ['sx','std. deviation'], ImgNumRange, PlotStartC, PlotEndC) plot_compare_graph (StatSxPoly, StatSxDiv, WindowlHandleCmp, ['Standard deviation - Sx','(comparison)'], ['polynomial','divisional'], ImgNumRange) inspect_images (WindowHandle, WindowHandleDiv, NumImgs, NumImgsSkip, PlotStartC, PlotEndC, Indices, ImgsBaseFN, 'Sx - Division') wait_seconds (.5) * Inspect Cy plot_stats_graph (StatCyDiv, WindowHandleDiv, 'Cy - Division', [], true, ['sy','std. deviation'], ImgNumRange, PlotStartC, PlotEndC) plot_stats_graph (StatCyPoly, WindowHandlePoly, 'Cy - Polynomial', [], true, ['sy','std. deviation'], ImgNumRange, PlotStartC, PlotEndC) plot_compare_graph (StatCyPoly, StatCyDiv, WindowlHandleCmp, ['Standard deviation - Cy','(comparison)'], ['polynomial','divisional'], ImgNumRange) inspect_images (WindowHandle, WindowHandleDiv, NumImgs, NumImgsSkip, PlotStartC, PlotEndC, Indices, ImgsBaseFN, 'Cy - Division') disp_message (WindowHandle, 'End of program', 'window', 12, 12, 'black', 'true') gray_window (WindowHandleDiv) gray_window (WindowHandlePoly) gray_window (WindowlHandleCmp)
(3)获取内参二
ImgPath := '3d_machine_vision/calib/' dev_close_window () dev_open_window (0, 0, 652, 494, 'black', WindowHandle) dev_update_off () dev_set_draw ('margin') dev_set_line_width (3) OpSystem := environment('OS') set_display_font (WindowHandle, 14, 'mono', 'true', 'false') * * Calibrate the camera. * StartCamPar := [0.016,0,0.0000074,0.0000074,326,247,652,494] create_calib_data ('calibration_object', 1, 1, CalibDataID) set_calib_data_cam_param (CalibDataID, 0, 'area_scan_division', StartCamPar) set_calib_data_calib_object (CalibDataID, 0, 'caltab_30mm.descr') NumImages := 10 * Note, we do not use the image from which the pose of the measurement plane can be derived for I := 1 to NumImages by 1 read_image (Image, ImgPath + 'calib_' + I$'02d') dev_display (Image) find_calib_object (Image, CalibDataID, 0, 0, I, [], []) get_calib_data_observ_contours (Caltab, CalibDataID, 'caltab', 0, 0, I) dev_set_color ('green') dev_display (Caltab) endfor calibrate_cameras (CalibDataID, Error) get_calib_data (CalibDataID, 'camera', 0, 'params', CamParam) * Write the internal camera parameters to a file write_cam_par (CamParam, 'camera_parameters.dat') Message := 'Interior camera parameters have' Message[1] := 'been written to file' disp_message (WindowHandle, Message, 'window', 12, 12, 'red', 'false') clear_calib_data (CalibDataID)

