相机标定去畸变和图像自标定去畸变的比较

* This example program compares the accuracies of the camera parameters
* that are computed with the regular camera calibration and the radial
* distortion self-calibration. 
* 采用两种不同的标定方法来比较径向畸变
* In the first part of the program, the camera is calibrated with the camera calibration.  In the second part
* of the program, the camera is calibrated with the radial distortion
* self-calibration.  The third part of the program compares the accuracies
* of the camera parameters numerically, by subtracting two images that
* were rectified with both sets of calibrated camera parameters, and
* by comparing the location of subpixel-precise edges that are extractedfrom both rectified images.
* 第一部分采用相机标定的方法。第二部分采用径向畸变自标定的方法。第三部分对摄像机参数的精度进行了数值比较,
* 第三部分分别通过图像间的差值和图像的边缘差别进行比较
* In particular, it can be seen that the radial distortion coefficient differs by less than 0.4% and that the
* calibrated principal point lies quite close to the center of radial
* distortions determined by the self-calibration.  Furthermore, it can be
* seen that the rectified images are very similar.  The position of the
* extracted subpixel-precise edges differs by less than 0.5 pixels
* throughout the entire field of view.
* 一般来说,当畸变系数差值小于0.4%时,相机标定得到的主点和自标定得到的畸变中心是非常接近的。
* 可以看出他们矫正的图像是非常相似的,提取的亚像素边缘的差值在整个视场中是小于0.5%
dev_update_off ()
dev_close_window ()
dev_open_window_fit_size (0, 0, 646, 482, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_set_line_width (3)
* 
* Part 1: Camera calibration----相机标定
* Perform the camera calibration.
CaltabName := 'caltab_30mm.descr'
gen_cam_par_area_scan_division (0.008, 0, 0.0000073, 0.0000073, 323, 241, 646, 482, StartCamPar)
create_calib_data ('calibration_object', 1, 1, CalibDataID)
set_calib_data_cam_param (CalibDataID, 0, [], StartCamPar)
set_calib_data_calib_object (CalibDataID, 0, CaltabName)
NumImages := 15
for I := 1 to NumImages by 1
    read_image (Image, 'radius-gauges/calib-' + I$'02d')
    dev_display (Image)
    disp_message (WindowHandle, 'Calibration marks in image ' + I$'d', 'window', 12, 12, 'black', 'true')
    find_calib_object (Image, CalibDataID, 0, 0, I, [], [])
    get_calib_data_observ_contours (Caltab, CalibDataID, 'caltab', 0, 0, I)
    get_calib_data_observ_points (CalibDataID, 0, 0, I, Row, Column, Index, Pose)
    gen_cross_contour_xld (Cross, Row, Column, 3.5, 0.785398)
    dev_set_color ('cyan')
    dev_display (Caltab)
    dev_set_color ('magenta')
    dev_display (Cross)
    wait_seconds (0.1)
endfor
dev_clear_window ()
disp_message (WindowHandle, 'Performing camera calibration...', 'window', 12, 12, 'black', 'true')
* Since the radial distortion self-calibration assumes square pixels, we
* force the camera calibration to use square pixels as well to enable a
* meaningful comparison of the results.
* 由于径向畸变自标定假设为正方形像素,我们强制摄像机标定使用正方形像素,以便对结果进行有意义的比较。
set_calib_data (CalibDataID, 'camera', 'general', 'excluded_settings', ['sx','sy'])
calibrate_cameras (CalibDataID, Error)
get_calib_data (CalibDataID, 'camera', 0, 'params', CamParCalib)
* Convert the camera parameters into pixel units so that they can be
* compared to the results of the radial distortion self-calibration.
* 将相机参数转换为像素单位,这样就可以与径向畸变自校正结果进行比较
get_cam_par_data (CamParCalib, 'kappa', Kappa)
get_cam_par_data (CamParCalib, 'sx', Sx)
* 
set_cam_par_data (CamParCalib, 'kappa', Kappa * Sx * Sx, CamParCalib)
set_cam_par_data (CamParCalib, ['sx','sy'], [1.0,1.0], CamParCalib)
* 
dev_clear_window ()
get_cam_par_data (CamParCalib, ['kappa','cx','cy'], CamParCalibValue)
disp_message (WindowHandle, 'Camera parameters (pixel-based units):', 'window', 12, 12, 'black', 'true')
CalibrationResultMsg := ' Kappa: ' + CamParCalibValue[0]$'11.5g'
CalibrationResultMsg[1] := ' Cx:    ' + CamParCalibValue[1]$'5.2f'
CalibrationResultMsg[2] := ' Cy:    ' + CamParCalibValue[2]$'5.2f'
disp_message (WindowHandle, CalibrationResultMsg, 'window', 50, 12, 'white', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 
* Part 2: self-calibration
read_image (Image, 'radius-gauges/radius-gauges-06')
* Extract subpixel-precise edges using the Canny filter.
edges_sub_pix (Image, Edges, 'canny', 1, 10, 40)
* Segment the edges into lines and circular arcs to break up edges that
* run around the squares in the image.
segment_contours_xld (Edges, EdgesSplit, 'lines_circles', 5, 4, 2)
dev_set_colored (12)
dev_set_line_width (2)
dev_display (Image)
dev_display (EdgesSplit)
disp_message (WindowHandle, 'Extracted and segmented edges', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* Merge collinear contours to obtain long contours in the image.
union_collinear_contours_ext_xld (EdgesSplit, EdgesUnion, 30, 2, 3, rad(10), 2, -1, 1, 1, 1, 1, 1, 0, 'attr_keep')
* Segment the merged edges into lines and circular arcs.
segment_contours_xld (EdgesUnion, EdgesUnionSplit, 'lines_circles', 5, 4, 2)
* Select edges that are long enough to be useful for the calibration.
select_shape_xld (EdgesUnionSplit, EdgesSelected, 'contlength', 'and', 30, 100000)
dev_display (Image)
dev_display (EdgesSelected)
disp_message (WindowHandle, 'Merged and selected edges', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
dev_clear_window ()
disp_message (WindowHandle, 'Performing self-calibration...', 'window', 12, 12, 'black', 'true')
* Perform the self-calibration of the radial distortions.
radial_distortion_self_calibration (EdgesSelected, EdgesCalibration, 646, 482, 0.1, 42, 'division', 'variable', 0, CamPar)
get_cam_par_data (CamPar, ['kappa','cx','cy'], CamParSelfCalibValue)
dev_clear_window ()
disp_message (WindowHandle, 'Compare camera parameters:', 'window', 12, 12, 'black', 'true')
SelfCalibrationResultMsg := ' Kappa: ' + CamParSelfCalibValue[0]$'11.5g'
SelfCalibrationResultMsg[1] := ' Cx:    ' + CamParSelfCalibValue[1]$'5.2f'
SelfCalibrationResultMsg[2] := ' Cy:    ' + CamParSelfCalibValue[2]$'5.2f'
disp_message (WindowHandle, ['Camera calibration:',CalibrationResultMsg], 'window', 50, 12, 'white', 'false')
disp_message (WindowHandle, ['Self-calibration:',SelfCalibrationResultMsg], 'window', 50, 280, 'white', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 
* Part 3: Compare results
get_domain (Image, Domain)
* Compute the camera parameters of the rectified cameras for both
* calibration results.
change_radial_distortion_cam_par ('fixed', CamParCalib, 0, CamParCalibRect)
change_radial_distortion_cam_par ('fixed', CamPar, 0, CamParRect)
* Rectify the image using both calibration results.
change_radial_distortion_image (Image, Domain, ImageCalibRectified, CamParCalib, CamParCalibRect)
change_radial_distortion_image (Image, Domain, ImageRectified, CamPar, CamParRect)
* Display the both rectified images five times to visualize the
* differences between the images.  The differences are most notable in
* the upper left and lower right corners of the image.
for J := 1 to 5 by 1
    dev_display (ImageCalibRectified)
    disp_message (WindowHandle, 'Rectified image (camera calibration)', 'window', 12, 12, 'black', 'true')
    wait_seconds (0.5)
    dev_display (ImageRectified)
    disp_message (WindowHandle, 'Rectified image (self-calibration)', 'window', 12, 12, 'black', 'true')
    wait_seconds (0.5)
endfor
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* Subtract the rectified images to visualize the differences of both
* calibration results.
sub_image (ImageRectified, ImageCalibRectified, ImageSub, 1, 128)
dev_display (ImageSub)
disp_message (WindowHandle, 'Difference between the rectified images', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* Extract edges in both rectified images to provide a different method
* for visualizing the differences of the calibration results.
edges_sub_pix (ImageRectified, EdgesRectified, 'canny', 1, 20, 40)
edges_sub_pix (ImageCalibRectified, EdgesCalibRectified, 'canny', 1, 20, 40)
select_shape_xld (EdgesRectified, EdgesRectified, 'contlength', 'and', 2, 10000)
select_shape_xld (EdgesCalibRectified, EdgesCalibRectified, 'contlength', 'and', 2, 10000)
* Display five different parts of the rectified image along with the
* subpixel-precise edges extracted from both rectified images in a zoom
* window to show the positional differences of the subpixel-precise edges.
* In particular, this display shows that the difference of the positions
* of the subpixel-precise edges is never more than about half a pixel.
get_window_extents (WindowHandle, Row1, Column1, Width, Height)
dev_open_window (0, Width + 8, 256, 256, 'black', WindowHandleZoom)
Rows := [16,45,465,408,233]
Cols := [45,620,37,610,307]
for J := 0 to |Rows| - 1 by 1
    dev_set_window (WindowHandle)
    dev_display (ImageRectified)
    dev_set_color ('yellow')
    dev_set_line_width (3)
    dev_set_draw ('margin')
    gen_rectangle1 (Rectangle, Rows[J] - 16, Cols[J] - 16, Rows[J] + 15, Cols[J] + 15)
    dev_display (Rectangle)
    disp_message (WindowHandle, 'Compare subpixel edges', 'window', 52, 12, 'black', 'true')
    dev_set_window (WindowHandleZoom)
    dev_set_part (Rows[J] - 16, Cols[J] - 16, Rows[J] + 15, Cols[J] + 15)
    dev_display (ImageRectified)
    dev_set_line_width (1)
    dev_set_color ('magenta')
    dev_display (EdgesCalibRectified)
    dev_set_color ('cyan')
    dev_display (EdgesRectified)
    if (J < |Rows| - 1)
        disp_continue_message (WindowHandle, 'black', 'true')
        stop ()
    endif
endfor

你可能感兴趣的:(halcon)