In-depth understanding of halcon camera calibration

  • Blogger writing is not easy, you still need your encouragement
  • Thousands of waters and thousands of mountains are always in love, so please click a like first.

Recently, some people wrote me privately, saying that after reading my "HALCON Camera Calibration Camera Internal Reference Camera External Reference" https://blog.csdn.net/cashmood/article/details/100089295, there are still some things I don’t understand, here Give everyone an in-depth tutorial.

Introduction to camera calibration

First of all, the lens is distorted, that is to say, the image that is photographed does not match the actual situation. Even industrial lenses have a distortion rate of a few thousandths.
The last picture tells you about the distortion. In
Insert picture description here
this picture, the first picture is the real shape under our camera, and the next two are the distorted pictures.

Secondly, the lens and camera, no matter how precise your mechanical structure is, it is not easy or impossible to install the camera in a particularly correct manner. Incorrect installation of the camera will also cause errors. If you want to know the specific mathematical model, you can search for the theoretical knowledge of camera calibration. I will focus on how to do it.
Calibration is to convert the above two things into normal.
Whether in image measurement or machine vision applications, the calibration of camera parameters is a very critical link. The accuracy of the calibration results and the stability of the algorithm directly affect the accuracy of the results produced by the camera.

In-depth description

1. Introduction to camera calibration parameters

Insert picture description here
Internal parameters: Determine the projection relationship of the camera from three-dimensional space to two-dimensional space.
The pinhole camera (FA lens camera) model has 6 parameters (f, kSx, Sy, Cx, Cy); the telecentric lens camera model has 5 parameters (f, Sx, Sy, Cx, Cy); the line scan camera is 11 parameters (f, k, Sx, Sy, Cx, Cy, Width, Highth, Vx, Vy, Vz).
Among them:
f is the focal length;
k is the radial distortion level. If k is negative, the distortion becomes barrel distortion, if it is positive, then the distortion becomes pincushion distortion.
Sx, Sy are scaling factors. For a pinhole camera (FA lens), it indicates the distance between adjacent pixels in the horizontal and vertical directions of the image sensor. The closer the initial value and the true value, the faster the calculation speed. For the telecentric camera model, it represents the size of the pixel in the world coordinate system.
Cx, Cy are the principal points of the image. For a pinhole camera, this point is the vertical projection of the projection center on the imaging plane, and it is also the center of radial distortion. For the telecentric camera model, only the center of distortion is represented.
Vx, Vy, Vz: The line scan camera must move relative to the object to be able to capture a useful image. This is the motion vector. Sx and Sy are the horizontal and vertical distances of adjacent pixels for line scan cameras.

2. Detailed introduction of calibration board

Question 1: Can halcon only use halcon-specific calibration boards?

Halcon provides simple and accurate calibration operators and calibration assistants, which greatly facilitates users in actual use
. There are two calibration methods in halcon:
halcon's own routines appear in the halcon-defined calibration board, As shown in the figure below:
Insert picture description here
user-defined calibration board, the user can make any shape and form of calibration board, as shown in the following figure:
Insert picture description here
Therefore, halcon can not only use a dedicated calibration board, but also can use a custom calibration board to perform calibration.

Question 2: How to generate the halcon calibration board?

Use gen_caltab operator to make a calibration board
gen_caltab(:: XNum, YNum, MarkDist, DiameterRatio, CalPlateDescr, CalPlatePSFile:) XNum:
the number of black marking dots in each row
YNum: the number of black marking dots in each column
MarkDist: two The distance between the centers of the nearest black dots, the unit is m
DiameterRatio: the ratio of the diameter of the black dots to the distance between the centers of the two dots
CalPlateDescr: the file path of the calibration plate description file
CalPlatePSFile: the path of the calibration plate image file, you can open the
example with ps :
gen_caltab( 7, 7, 0.1, 0.5,'caltab.descr','caltab.ps')
You can think about the meaning of each parameter for yourself.
Number of rows: 7
Number of columns: 7
Black dot radius: 0.05m
dot center Spacing: 0.1m

Question 3: How to place the halcon calibration board and is there a limit to the number of photos taken?

It is not that the larger the number of camera calibrations, the higher the accuracy that can be achieved. Halcon recommends that the number of shots be 9-16, and also makes suggestions for placement. The calibration board occupies 1/3-1/4 of the calibration field of view, and the image gray value of the calibration board should be greater than 128 for smooth extraction. As shown below:
Insert picture description here

Calibration steps

Note that only the area scan camera is introduced, other cameras are ideally the same as the area scan channel.

1. Set the initial value of the camera

Use the set_calib_data_cam_param operator to set the internal initial value of the camera

set_calib_data_cam_param(:: CalibDataID, CameraIdx, CameraType, CameraParam:)
CalibDataID: calibration handle
CameraIdx: camera serial number
CameraType: camera model type; area scan camera Division distortion model'area_scan_division'; polynomial distortion model'area_scan_polynomial'. . . . . .
CameraParam: the parameters corresponding to the camera model; the area scan camera Division distortion model'area_scan_division' ([Focus, Kappa, Sx, Sy, Cx, Cy, ImageWidth, ImageHeight]); the polynomial distortion model'area_scan_polynomial' ([Focus, K1, K2, K3, P1, P2, Sx, Sy, Cx, Cy, ImageWidth, ImageHeight]). . . . . .

The corresponding table of camera model types and camera parameters:
Insert picture description here

Distortion type selection and parameter determination skills

Distortion model selection
division distortion model is only suitable for low-precision cases where the number of calibration pictures is small:
polynomial distortion model corrects both radial and tangential distortions, with higher accuracy and longer time.
Parameter determination skills
Focus represents focal length, fill in according to our lens parameters, and fill in 0 for telecentric lens

Kappa is the distortion size, because before calibration, 0 is filled in by default

The width and height of Sx, Sy pixel fill in the pixel size of the camera. You can check the camera manual, or consult the camera manufacturer.
Cx, Cy fill in the center coordinates of the image
ImageWidth, ImageHeight fill in the width and height of the image

2. Initialize the calibration board

Use the operator set_calib_data_calib_object
for example:
CaltabDescr :='caltab_100mm.descr'
set_calib_data_calib_object (CalibDataID, 0, CaltabDescr)
This is relatively simple, you can understand it by reading the help, so I won’t introduce it.

3. Create a calibration data model

Use the operator create_calib_data(:: CalibSetup, NumCameras, NumCalibObjects: CalibDataID)
CalibSetup: content created
NumCameras: number of cameras
NumCalibObjects: number of calibration items
CalibDataID: calibration handle
For example:
create_calib_data ('calibration_object', 1, 1, CalibDataID)

4. Obtain calibration pictures

The calibration plate is square, the size is 1/3 of the width of the area to be irradiated, the camera takes or reads 9-16 pictures, the calibration plate tries to cover the entire field of view when taking pictures; the diameter of the dots of the calibration plate cannot be less than 10 pixels .

5. Use the image to calibrate the camera internal parameters and get the result

Method 1:
Use the calibration image, directly use halcon to fully automate the calibration
find_calib_object (Image, CalibDataID, CameraIndex, 0, PoseIndex, [], []) to
get the calibration data
get_calib_data (CalibDataID,'camera', 0,'type', CameraType)

Method 2:
1. Find the calibration plate area, determine the center of the circle, and load the result into the component
find_caltab(Image: CalPlate: CalPlateDescr, SizeGauss, MarkThresh, MinDiamMarks
:) find_marks_and_pose(Image, CalPlateRegion:: CalPlateDescr, StartCamParam, StartThresh, DeltaThresh, DeltaThresh MinThresh, Alpha, MinContLength, MaxDiamMarks: RCoord, CCoord, StartPose)
set_calib_data_observ_points(:: CalibDataID, CameraIdx, CalibObjIdx, CalibObjPoseIdx, Row, Column, Index, Pose
:) Principle: First find the image Size_Gauss filter ), and then threshold segmentation (the threshold size is MarkThresh) to find out the area of ​​the calibration plate; find_marks_and_pose operator divides the circle in the area, find the number of circles, perimeter, coordinates, etc. should be consistent with the calibration plate description file , Otherwise it will automatically adjust StartThresh so that StartThresh is reduced to MinDiamMarks according to the DeltaThresh step length until the exact center of the circle is found.
2. Perform calibration
calibrate_cameras (:: CalibDataID: Error) and
return the average projection error Error

6. Use the image to calibrate the camera external parameters and get the result

Camera external parameters: determine the relative position relationship between the camera coordinate system and the world coordinate system,
where Pw is the world coordinate, Pc is the camera coordinate, T=(Tx,Ty,Tz) is the translation vector, R=(a,b,r) Is the rotation matrix, the rotation angle around the Z axis of the camera coordinate system is r; the rotation angle around the Y axis of the camera coordinate system is b; the rotation angle around the X axis of the camera coordinate system is a. 6 parameters form the camera external parameters (a, b, r, Tx, Ty, Tz)
and satisfy the following formula:
Pc=R*Pw+T

具体步骤:
set_calib_data_cam_param (:: CalibDataID, CameraIdx, CameraType, CameraParam:)
set_calib_data_calib_object (:: CalibDataID, CalibObjIdx, CalibObjDescr:)
find_calib_object (Image:: CalibDataID, CameraIdx, CalibObjIdx, CalibObjPoseIdx, GenParamName, GenParamValue:)
get_calib_data_observ_contours (: Contours: CalibDataID, ContourName, CameraIdx, CalibObjIdx, CalibObjPoseIdx:)
get_calib_data_observ_points (:: CalibDataID, CameraIdx, CalibObjIdx, CalibObjPoseIdx: Row, Column, Index, Pose)
set_origin
Insert picture description here

Halcon camera calibration code and analysis

**创建标定板
gen_caltab(7,7,0.008,0.5,'48_48mm.descr','48_48mm.ps')
           
*=======标定内参
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')
           
*标定相机
StartCamPar := [0.0,0.0,0.0000299,0.0000299,4896/2,3264/2,4896,3264]
create_calib_data ('calibration_object', 1, 1, CalibDataID)
set_calib_data_cam_param (CalibDataID, 0, 'area_scan_telecentric_division', StartCamPar)
set_calib_data_calib_object (CalibDataID, 0, '48_48mm.descr')
           

for index := 1 to 13 by 1
    read_image (Image, '标定20/' + index + '.png')
    get_image_size(Image, Width, Height)
    dev_display (Image)
    find_calib_object (Image, CalibDataID, 0, 0, index, [], [])
    get_calib_data_observ_contours (Caltab, CalibDataID, 'caltab', 0, 0, index)
    dev_set_color ('green')
    dev_display (Caltab)
endfor
           
calibrate_cameras (CalibDataID, Error)
get_calib_data (CalibDataID, 'camera', 0, 'params', CamParam)
get_calib_data (CalibDataID, 'calib_obj_pose', [0,1], 'pose', PoseCalib)
           
*输出计算的相机内参
write_cam_par (CamParam, 'camera_parameters.dat')
           
           
Message:= '相机内参已经写入文件中'
disp_message (WindowHandle, Message, 'window', 12, 12, 'red', 'false')
clear_calib_data (CalibDataID)
stop()
           
           
*=====标定外参
dev_set_draw ('margin')
dev_set_line_width (1)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
           
*从文件中读取内参 存储文件:camera_parameters.dat
try
    read_cam_par ('camera_parameters.dat', CamParam)
catch (Exception)
    stop ()
endtry
           
*开始计算
open_file('data.csv','output', FileHandle)
fwrite_string(FileHandle,'Dis_pix*0.0299204,Dis_m*1000,Distance')
fnew_line (FileHandle)
close_file(FileHandle)
           
*选择一张作为标定作为最终标定位姿(任意一张都可以)
index:=1
read_image (Image,'标定20/'+index+'.png')
dev_display (Image)
CaltabName := '48_48mm.descr'
create_calib_data ('calibration_object', 1, 1, CalibDataID)

set_calib_data_cam_param (CalibDataID, 0, 'area_scan_telecentric_division', CamParam)
set_calib_data_calib_object (CalibDataID, 0, CaltabName)
find_calib_object (Image, CalibDataID, 0, 0, 1, [], [])
get_calib_data_observ_contours (Caltab, CalibDataID, 'caltab', 0, 0, 1)
get_calib_data_observ_points (CalibDataID, 0, 0, 1, RCoord, CCoord, Index, PoseForCalibrationPlate)
dev_set_color ('green')
dev_display (Caltab)
dev_set_color ('red')
disp_caltab (WindowHandle, CaltabName, CamParam, PoseForCalibrationPlate, 1)
dev_set_line_width (1)
disp_circle (WindowHandle, RCoord, CCoord, gen_tuple_const(|RCoord|,1.5))
* caltab_points (CaltabName, X, Y, Z)
* calibrate_cameras (CalibDataID, Error)
* To take the thickness of the calibration plate into account, the z-value
* of the origin given by the camera pose has to be translated by the
* thickness of the calibration plate.
* Deactivate the following line if you do not want to add the correction.
set_origin_pose (PoseForCalibrationPlate, 0, 0, 0, PoseCalib)
* disp_continue_message (WindowHandle, 'black', 'true')
* stop ()
           
*像素距离
distance_pp(RCoord[0],CCoord[0],RCoord[48],CCoord[48], Dis_pix)
*像素直接转换mm然后计算
pix2mm(RCoord, CCoord,CamParam[2],CamParam[3],newCol,newRow)
distance_pp(newRow[0],newCol[0],newRow[48],newCol[48], Dis_m)
*用同一个世界坐标系来计算
image_points_to_world_plane(CamParam, PoseCalib,[RCoord[0],RCoord[48]], [CCoord[0],CCoord[48]], 'mm', X1, Y1)
distance_pp(Y1[0],X1[0],Y1[1],X1[1],Distance)
           
*输出计算结果比较
open_file('data.csv','append', FileHandle)
fwrite_string(FileHandle, Dis_pix*0.0299+','+Dis_m*1000+','+Distance+'\n')
close_file(FileHandle)    
           
Message:= '计算完毕'
disp_message (WindowHandle, Message, 'window', 12, 12, 'red', 'false')
stop()

This document is shared and organized by http://www.ihalcon.com/read-7598.html.

  • About the blogger:
  • Industrial automation upper computer software engineer, machine vision algorithm engineer, motion control algorithm engineer. Currently working in the intelligent manufacturing automation industry. Blogger's mailbox: [email protected]
  • Help me like it. Haha.

Guess you like

Origin blog.csdn.net/cashmood/article/details/105221053