Halcon self-calibration for distortion correction

1. Halcon has an operator that can use a single image to calibrate the internal parameters of the camera for distortion correction. However, there are requirements for the picture, because the closer the distortion is to the edge of the image, the more serious it will be. Therefore, it is required that there are enough straight lines around the picture, and it is best to have enough straight lines in the middle of the image. These straight lines are extracted, and after calibration later, these distorted straight lines will be straightened to achieve distortion correction. This function is similar to the CheckBoard calibration in Visionpro, except that after the CheckBoard calibration, the pixel coordinates can be directly converted to the world coordinates, and the converted image can be directly output in mm for measurement. However, after the Halcon self-calibration operator is calibrated, it can only be used for distortion correction. If it needs to be used to convert to world coordinates, it needs to calculate the pixel equivalent.
2. Operator detailed explanation
2.1 radial_distortion_self_calibration(Contours : SelectedContours : Width, Height, InlierThreshold, RandSeed, DistortionModel, DistortionCenter, PrincipalPointVar : CameraParam)

Name: Radial Distortion Self-Calibration
Description: This operator uses the XLD profile data to estimate the distortion parameters and distortion center of the lens. Even the obtained parameters are returned through the internal parameter CameraParam of the camera. This operator cannot correct for focal length and scale factors, so it cannot be used in 3D measurements.

Parameters:
Contours: Contour data input for correction
SelectedContours: Corrected contour data
Width: Image width of obtained contour data
Height: Image height of obtained contour data
InlierThreshold: Classification threshold
RandSeed: Random seed
DistortionModel: Distortion mode
DistortionCenter: Distortion center estimation mode, which determines the method to estimate the distortion center. There are 'variable' (default, suitable for image edges with many contours or distortion should be high. Otherwise, ill-posedness may occur when finding the distortion center, leading to instabilities.) 'adaptive' (this method should be used if it can be assumed that the distortion center is near the center of the image and only few contours are available or other contours are in bad positions (e.g. the contours have the same direction), 'fixed' (this method is suitable for weak distortions or few contours, in bad positions.) PrincipalPointVar: deviation control, control the deviation between the distortion center and the image center CameraParam: output camera
internal
parameters

2.2 change_radial_distortion_cam_par( : : Mode, CamParamIn, DistortionCoeffs : CamParamOut)

Name: Distortion Correction Parameters
Description: According to the specified radial distortion coefficient, find the ideal undistorted camera internal parameters.
parameter:

Mode: Distortion mode
CamParamIn: Distorted camera internal parameters
DistortionCoeffs: Distortion coefficient value
CamParamOut: Corrected camera internal parameters

2.3 change_radial_distortion_image(Image, Region : ImageRectified : CamParamIn, CamParamOut : )
Name: Correct the distorted image
Description: Correct the distortion of the input image according to the specified image and the specified addition parameters. change_radial_distortion_image changes the radial distortion of the input image according to the internal camera parameters CamParamIn and CamParamOut. Use CamParamOut to convert each pixel of the output image lying within the region region to an image plane, then use CamParamIn to project it as a sub-pixel of the image. The resulting gray value is determined by bilinear interpolation. If the sub-pixel is outside the image, the corresponding pixel in the image reconstruction is set to "black" and eliminated from the image domain.

Parameters:
Image: Input image
Region: Corrected image area
ImageRectified: Corrected image
CamParamIn: Input camera parameters
CamParamOut: Output camera parameters
2.4 gen_radial_distortion_map(Map, CameraParam, CamParamOut, 'bilinear')
map_image(Imagecalib, Map, ImageMapped)
The combination of these two operators can realize the image distortion correction function of 2.3.
3. Case
3.1 Halcon official case

*这个程序展示了如何radial_distortion _selfcalibration可以用来
*校准径向畸变系数和中心
*扭曲。在程序的第一部分,从边缘提取
*一个图像用于校准。结果表明
*径向畸变提取相当准确的从单一
*图像。为了提高准确性,程序的第二部分显示
*如何从20张图像中提取的边缘可以用来执行
*校准。因为这些边出现在很多不同的方向
* 20张图片,主点可以确定的明显更多
*准确。
dev_update_off ()
read_image (Image, 'board/board-01')
dev_close_window ()
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_display (Image)
disp_message (WindowHandle, 'Image with radial distortions', 'window', 0, 0, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 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.
segment_contours_xld (Edges, SplitEdges, 'lines_circles', 5, 4, 2)
* Select edges that are long enough to be useful for the calibration.
select_shape_xld (SplitEdges, SelectedEdges, 'contlength', 'and', 30, 100000)
dev_display (Image)
dev_set_colored (12)
dev_display (SelectedEdges)
disp_message (WindowHandle, 'Extracted edges', 'window', 0, 0, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
dev_clear_window ()
disp_message (WindowHandle, 'Performing self-calibration...', 'window', 0, 0, 'black', 'true')
*执行径向畸变的自我校准。
radial_distortion_self_calibration (SelectedEdges, CalibrationEdges, 646, 492, 0.08, 42, 'division', 'variable', 0, CamParSingleImage)
*校正图像,即去除径向畸变。
get_domain (Image, Domain)
change_radial_distortion_cam_par ('fixed', CamParSingleImage, 0, CamParSingleImageRect)
change_radial_distortion_image (Image, Domain, ImageRectified, CamParSingleImage, CamParSingleImageRect)
* Display the distorted and undistorted image five times to visualize the
* differences between the images.
dev_display (Image)
dev_display (CalibrationEdges)
disp_message (WindowHandle, 'Edges used for calibration', 'window', 0, 0, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
dev_display (ImageRectified)
disp_message (WindowHandle, 'Image without radial distortions', 'window', 0, 0, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* Now perform the self-calibration using edges extracted from 20 images.
* The variable Edges will accumulate the edges extracted from the images.
gen_empty_obj (Edges)
for J := 1 to 20 by 1
    read_image (Image, 'board/board-' + J$'02d')
    * Extract subpixel-precise edges using the Canny filter.
    edges_sub_pix (Image, ImageEdges, 'canny', 1, 10, 40)
    * Segment the edges into lines and circular arcs.
    segment_contours_xld (ImageEdges, SplitEdges, 'lines_circles', 5, 4, 2)
    * Select edges that are long enough to be useful for the calibration.
    select_shape_xld (SplitEdges, SelectedEdges, 'contlength', 'and', 30, 100000)
    * Accumulate the edges.
    concat_obj (Edges, SelectedEdges, Edges)
    dev_display (Image)
    dev_set_colored (12)
    dev_display (SelectedEdges)
    disp_message (WindowHandle, 'Edges extracted from image ' + J$'d', 'window', 0, 0, 'black', 'true')
endfor
dev_clear_window ()
dev_set_colored (12)
dev_display (Edges)
disp_message (WindowHandle, 'Collected edges from multiple images', 'window', 0, 0, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
dev_clear_window ()
disp_message (WindowHandle, 'Performing self-calibration...', 'window', 0, 0, 'black', 'true')
*执行径向畸变的自我校准。
radial_distortion_self_calibration (Edges, CalibrationEdges, 646, 492, 0.08, 42, 'division', 'variable', 0, CamParMultiImage)
dev_clear_window ()
dev_set_colored (12)
dev_display (CalibrationEdges)
disp_message (WindowHandle, 'Edges used for calibration', 'window', 0, 0, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*计算未失真图像的相机参数。
change_radial_distortion_cam_par ('fixed', CamParMultiImage, 0, CamParMultiImageRect)
for J := 1 to 20 by 1
    read_image (Image, 'board/board-' + J$'02d')
    get_domain (Image, Domain)
    *校正图像,即去除径向畸变。
    change_radial_distortion_image (Image, Domain, ImageRectified, CamParMultiImage, CamParMultiImageRect)
    * Display the distorted and undistorted image to visualize the
    * differences between the images.
    dev_display (Image)
    disp_message (WindowHandle, 'Image with radial distortions', 'window', 0, 0, 'black', 'true')
    wait_seconds (0.5)
    dev_display (ImageRectified)
    disp_message (WindowHandle, 'Image without radial distortions', 'window', 0, 0, 'black', 'true')
    wait_seconds (0.5)
endfor

Original image
insert image description here
XLD distortion correction used
insert image description here
for distortion correction Figure
insert image description here
3.2 Personal writing case

dev_update_off ()
read_image (Image, 'C:/Users/Dell/Desktop/Halocn自标定畸变校正/畸变校正.jpg')
get_image_size (Image, Width, Height)
dev_close_window ()
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_display (Image)
disp_message (WindowHandle, 'Image with radial distortions', 'window', 0, 0, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 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.
segment_contours_xld (Edges, SplitEdges, 'lines_circles', 5, 4, 2)
* Select edges that are long enough to be useful for the calibration.
select_shape_xld (SplitEdges, SelectedEdges, 'contlength', 'and', 30, 100000)
dev_display (Image)
dev_set_colored (12)
dev_display (SelectedEdges)
disp_message (WindowHandle, 'Extracted edges', 'window', 0, 0, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
dev_clear_window ()
disp_message (WindowHandle, 'Performing self-calibration...', 'window', 0, 0, 'black', 'true')
*名字:径向畸变自标定
*描述:此算子通过XLD轮廓数据来估算镜头的畸变参数和畸变中心。其获得的即便参数通过相机内参数CameraParam返回。
*此算子不能矫正焦距和比例因子,因此不能用于3D测量中。
*若相机模型为area(division),则相机参数为7个,若area(多项式),则相机参数12个。
*InlierThreshold值在0.010.5之间。值越小,精度越高,但是运算耗时长;值越大,越能容忍偏差。默认值0.05radial_distortion_self_calibration (SelectedEdges, CalibrationEdges, Width, Height, 0.08, 42, 'division', 'fixed', 0, CameraParam)
*名字:校正畸变参数
*描述:根据指定的径向畸变系数,求取理想无畸变的相机内参。
get_domain (Image, Domain)
change_radial_distortion_cam_par ('fixed', CameraParam, 0, CamParamOut)
*名字:校正畸变图像方法1
*描述:根据指定图像和指定相加参数来矫正输入图像的畸变。
change_radial_distortion_image (Image, Domain, ImageRectified, CameraParam, CamParamOut)
dev_display (Image)
dev_display (CalibrationEdges)

*校正畸变图像方法2,效果与方法1完全相同
gen_radial_distortion_map(Map, CameraParam, CamParamOut, 'bilinear')
map_image(Image, Map, ImageMapped)
dev_display (Image)
dev_display (ImageMapped)


*读写参数
* write_cam_par (CameraParam, 'D:/CameraParam.dat')
* write_cam_par (CamParamOut, 'D:/CamParamOut.dat')
* read_cam_par ('D:/CameraParam.dat', CameraParam1)
* read_cam_par ('D:/CamParamOut.dat', CamParamOut1)

original image
insert image description here

The image after XLD distortion correction used
insert image description here
for distortion correction
insert image description here
Original image The image after
insert image description here
XLD distortion correction used for distortion correction 4. Problems encountered When the radial_distortion_self_calibration function is executed, this error No stable solution found: please change the inlier threshold or select contours manually (HALCON error code: 3661) is reported. Solution: Set the DistortionCenter parameter of the operator radial_distortion_self_calibration to 'fixed' or 'adaptive'. If it is changed to 'fixed' or 'adaptive' and still report an error, then: (1) The value of InlierThreshold needs to be increased appropriately (2) The number of rows and columns of the checkerboard needs to be increased appropriately. 5. Summary
insert image description here

insert image description here


insert image description here






The operator of halcon self-calibration, it can calibrate the internal parameters of the camera (no focal length) without using a calibration board, and it is impossible to obtain the external parameters of the camera compared to multiple calibrations. Because the distortion is generally more severe at the edges of the image, it is necessary to ensure that there are enough straight line segments around the edges of the image. In the actual project, it is impossible for the objects to be shot to have ideal straight edges as in the routine. The alternative is: use film to make a grid black print (10*10, which can be adjusted according to your actual situation) to fill the entire field of view. Distortion correction can be performed after the camera’s internal reference is obtained. Therefore, self-calibration is faster in distortion correction than multi-frame calibration, so that the equipment is easier to operate and maintain on site. After distortion correction, we can also place a reference object to obtain the pixel equivalent, and construct an XY world coordinate system for applications such as measurement and positioning. If you need to convert pixel units to public units, you can also use checkerboards, standard objects, film sheets, etc. for conversion, and then apply it to measurement projects; you can also use a certain grid to construct an XY coordinate system for positioning projects, so that distortion correction and measurement projects can be performed without the use of calibration plates.

Guess you like

Origin blog.csdn.net/Douhaoyu/article/details/128330952