Halcon自标定做畸变校正

一、Halcon有个算子可以实现利用单张图像,标定出相机内参,用来做畸变校正。不过对图片有要求,因为畸变越靠近图像边缘,就会越严重。所以要求图片的四周有足够的直线,最好图像中间部分也有足够的直线。提取这些直线,后面标定之后会把这些产生畸变的直线拉直,实现畸变校正。这个功能类似Visionpro里面的CheckBoard标定,只不过CheckBoard标定后,可以直接把像素坐标转换到世界坐标,转换后的图用来测量可以直接输出毫米mm。而Halcon自标定算子标定后,只能用于畸变校正。如需要用于转换到世界坐标,需要另加计算像素当量。
二、算子详解
2.1 radial_distortion_self_calibration(Contours : SelectedContours : Width, Height, InlierThreshold, RandSeed, DistortionModel, DistortionCenter, PrincipalPointVar : CameraParam)

名字:径向畸变自标定
描述:此算子通过XLD轮廓数据来估算镜头的畸变参数和畸变中心。其获得的即便参数通过相机内参数CameraParam返回。此算子不能矫正焦距和比例因子,因此不能用于3D测量中。

参数:
Contours :输入用来矫正的轮廓数据
SelectedContours :矫正后的轮廓数据
Width:获取轮廓数据的图像宽度
Height:获取轮廓数据的图像高度
InlierThreshold:分类阈值
RandSeed:随机种子
DistortionModel:畸变模式
DistortionCenter:畸变中心的估算模式,决定使用何种方式估计失真中心。有 ‘variable’(默认,适用于图像边缘轮廓线很多或者失真应该很高。否则,在寻找畸变中心时可能会出现不适定性,从而导致不稳定性。)‘adaptive’(如果可以假定畸变中心位于图像中心附近,并且只有很少的等值线可用或其他等值线的位置不好(例如等值线方向相同),则应使用这种方法), ‘fixed’(该方法适用于失真很弱或轮廓线少的情况下,在不好的位置。)
PrincipalPointVar :偏差控制,控制畸变中心与图像中心的偏差
CameraParam:输出相机内参数

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

名字:矫正畸变参数
描述:根据指定的径向畸变系数,求取理想无畸变的相机内参。
参数:

Mode:畸变模式
CamParamIn:畸变的相机内部参数
DistortionCoeffs :畸变系数值
CamParamOut:已校正的相机内参

2.3 change_radial_distortion_image(Image, Region : ImageRectified : CamParamIn, CamParamOut : )
名字:矫正畸变图像
描述:根据指定图像和指定相加参数来矫正输入图像的畸变。change_radial_distortion_image根据摄像机内部参数CamParamIn和CamParamOut对输入图像图像的径向畸变进行改变。使用CamParamOut将位于区域区域内的输出图像的每个像素转换为图像平面,然后使用CamParamIn将其投影为图像的亚像素。通过双线性插值确定得到的灰度值。如果该亚像素在图像之外,则将图像重建中的对应像素设置为“黑色”并从图像域中消除。

参数:
Image:输入图像
Region :矫正图像的区域
ImageRectified :矫正图像
CamParamIn:输入相机参数
CamParamOut :输出相机参数
2.4 gen_radial_distortion_map(Map, CameraParam, CamParamOut, ‘bilinear’)
map_image(Imagecalib, Map, ImageMapped)
这两个算子联合可以实现2.3的图像畸变校正功能。
三、案例
3.1 Halcon官方案例

*这个程序展示了如何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

原图
Halcon自标定做畸变校正
用来畸变校正的XLD
Halcon自标定做畸变校正
畸变校正后的图
Halcon自标定做畸变校正
3.2 个人编写案例

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.01到0.5之间。值越小,精度越高,但是运算耗时长;值越大,越能容忍偏差。默认值0.05。
radial_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)

原图
Halcon自标定做畸变校正

用来畸变校正的XLD
Halcon自标定做畸变校正
畸变校正后的图
Halcon自标定做畸变校正

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
心中带点小风骚的头像心中带点小风骚普通用户
上一篇 2023年3月26日
下一篇 2023年3月26日

相关推荐