引言:
勇哥注:所谓的3d相机标定并不是指的3d相机的标定,而是指的是3d空间做相机的标定, 这个相机仍然是2D相机。 halcon的这套标定方法,同时可以应对测量、手眼标定。 并且由于是在3d空间做标定,因此你在做测量的时候相机和拍摄平面可以不是完全垂直, 或者物料可以任意方向倾斜(当然你的相机的景深要能做得到)。 如果你是做机器人手眼标定,这套标定方法无论是hand to eye,还是eye in hand,都可以搞定。 另外,你是四轴scara机器人还是串联的6轴机器人都可以的。 对于轴动的标定,也是没有问题的。 halcon的标定方法还可以实现相机标定和确定工作平面位姿进行分离。 这意味着你标定完相机后,你的测量平面可以随时改换。 halcon的这套3d相机标定方法不是一般的强,可以搞定现在工业机器视觉的绝大部分标定方面的应用。 至少勇哥还没发现有啥子应用它还做不到的。
径向畸变校准
首先要谈一下畸变的模形。
畸变主要分为径向畸变、切向畸变和薄棱镜畸变。
1.径向畸变
径向畸变主要由透镜本身导致的,远离透镜中心的光线比靠近中心的光线弯曲的更严重。图1显示矩形网格因镜像畸变而产生的位移。从前面看,光心越向外,矩形网格上的点的位移越大。
(图1.1)
(图1.2)
图1.1 透镜的径向畸变图,箭头显示径向畸变图像上外部矩形网格的偏移
图1.2 注解
图2显示了两种典型的径向畸变,分别为桶形畸变和枕形畸变
2.切向畸变
切向畸变主要由镜头安装导致,当透镜不完全平行于图像平面的时候产生切向畸变。下图显示了某透镜的切向畸变图像。
3.薄棱镜畸变
薄棱镜畸变一般由镜头设计和加工安装误差导致,一般情况下,可忽略此畸变。
径向畸变的校正方法
有两种:
(1)仅使用内参
(2)使用内参与位姿
(1) 仅使用内参
算子 change_radial_distortion_cam_par 根据指定的径向变形确定新的相机参数。
详细见:http://47.98.154.65/?id=1595
change_radial_distortion_image 更改图像的径向变形。详细见:http://47.98.154.65/?id=1598
演示代码是halcon的例程:change_radial_distortion_image.hdev
read_image (Image, 'pioneer') rgb1_to_gray (Image, GrayImage) gen_cam_par_area_scan_division (0.00219846, -78129.2, 5.46495e-06, 5.5e-06, 318.206, 236.732, 640, 480, CamParIn) change_radial_distortion_cam_par ('adaptive', CamParIn, 0, CamParOut) change_radial_distortion_image (GrayImage, GrayImage, ImageRectified, CamParIn, CamParOut)
另一种打法是:
change_radial_distortion_cam_param() 更新径向畸变参数 gen_radial_distorition_map() 形成映射矩阵 map_image() 图像映射
勇哥把上面例子改写一下:
read_image (Image, 'pioneer') rgb1_to_gray (Image, GrayImage) gen_cam_par_area_scan_division (0.00219846, -78129.2, 5.46495e-06, 5.5e-06, \ 318.206, 236.732, 640, 480, CamParIn) change_radial_distortion_cam_par ('adaptive', CamParIn, 0, CamParOut) *change_radial_distortion_image (GrayImage, GrayImage, ImageRectified, CamParIn, CamParOut) gen_radial_distortion_map(Map, CamParIn, CamParOut, 'bilinear') map_image(Image, Map, ImageMapped)
效果是一样的,只不过不是直接对图片进行处理,而是先生成一个映射图像,然后再用map_image校正图像。
使用这种方式主要是批量处理图片时占有速度上的优势,这个时候你可以用一张Map循环校正全部图片。
即map_image速度上优于直接change_radial_distortion_image。
另外一个生成校正映射图的算子是gen_arbitrary_distortion_map 生成投影图,该投影图描述任意失真的图像和校正后的图像之间的映射。
这个算子其效果上来看有点像透视畸变校正,勇哥也有点搞晕了,以后搞清楚区别再写一篇介绍一下吧。
(2) 使用内参与位姿
程序演示了如何校准径向畸变的图像,及怎么样把一个畸变图上的点转换为没有畸变的位置。
演示代码:
*该程序演示如何从径向畸变图像中提取点坐标进行校正。这是通过使用存储在相机参数(CamParam) *中的径向畸变参数来更改“径向畸变”点来完成的 dev_close_window () dev_update_off () read_image (Image, 'calib/calib_distorted_01.png') dev_open_window_fit_image (Image, 0, 0, [600,800], [400,600], WindowHandle) set_display_font (WindowHandle, 14, 'mono', 'true', 'false') dev_set_line_width (2) * Read camera parameters and prepare radially corrected camera parameters * 读取摄像机参数并准备径向修正的摄像机参数 gen_cam_par_area_scan_polynomial (0.00506526, 5142.64, -1.98485e+08, -4.26734e+12,\ 0.0462524, 0.114147, 9.30055e-06, 9.3e-06, 276.713, 266.078, 640, 512, CamParam) change_radial_distortion_cam_par ('fixed', CamParam, [0.0,0.0,0.0,0.0,0.0], CamParamOut) * for I := 18 to 34 by 1 Filename := 'calib/calib_distorted_' + I$'02' read_image (Image, Filename) * Convert image to 'byte' min_max_gray (Image, Image, 0, Min, Max, Range) scale_image_range (Image, ImageScaled, Min, Max) convert_image_type (ImageScaled, ByteImage, 'byte') * Find mark centers find_caltab (ByteImage, Caltab, 'caltab_100mm.descr', 3, 112, 5) find_marks_and_pose (ByteImage, Caltab, 'caltab_100mm.descr', CamParam,\ 128, 10, 18, 0.9, 15, 100, Row, Column, StartPose) * Rectify the mark centers * 校正标记中心 change_radial_distortion_points (Row, Column, CamParam, CamParamOut, RowChanged, ColChanged) * Prepare output points gen_cross_contour_xld (Cross, Row, Column, 12, rad(45)) gen_cross_contour_xld (CrossChanged, RowChanged, ColChanged, 12, rad(45)) * Show results dev_display (ByteImage) dev_set_color ('magenta') dev_display (Cross) dev_set_color ('green') dev_display (CrossChanged) ** *Extracted centers 提取中心 *Corrected centers 校正中心 disp_message (WindowHandle, ['Extracted centers (magenta \'x\')',\ 'Corrected centers (green \'x\')'], 'window', 10, 10, ['magenta','forest green'], 'true') wait_seconds (0.2) endfor disp_continue_message(WindowHandle, 'black', 'true') stop () change_radial_distortion_image (ByteImage, ByteImage, ImageRectified, CamParam, CamParamOut) dev_display (ByteImage) dev_set_color ('magenta') dev_display (Cross) disp_message (WindowHandle, 'Original image and extracted centers', 'window',\ 10, 10, 'magenta', 'true') disp_continue_message (WindowHandle, 'black', 'true') stop () dev_display (ImageRectified) dev_set_color ('green') dev_display (CrossChanged) disp_message (WindowHandle, 'Corrected image and centers', 'window', 10, 10,\ 'forest green', 'true')
下图中桃红色的点是提出的点,绿色是畸变校准后的点的位置。
这是原图及标定板上提取的点。
image被校正了径向畸变的效果。现在的绿色点都是被校正后的位置。可以理解为原来桃红色点与绿色点现在已经重合了。
最后谈几个问题:
(1) halcon能校准切向畸变吗
不知道,在网上根本没有人谈过halcon怎么进行切向畸变校准,到是opencv中有人谈到过。
(2) 定位应用中是先图像校正畸变再进行像素世界坐标的转换吗
是的。在要获取内参的位置请使用经过change_radial_distortion_cam_par修改后的内参。
(3) 怎么判断你的CCD拍出来的畸变类型?
不知道,没人谈论这个话题。
下面这篇文章谈到如果看你的图像是否畸变,但没有谈畸变类型。
如何测试成像畸变 http://47.98.154.65/?id=1190
(4) 透视畸变什么情况下用?
透视是个正常的现象,勇哥现在也不知道啥时候需要做透视畸变校准。上节课举的一个例子实际上只是演示有这么一个功能。
看了一下opencv中的透视畸变校正的例子,例如下图这样:
但是我们halcon是搞的机器视觉,不是用来搞这样的生活图片应用。如果有兄弟知道透视畸变的修正什么项目能用得上,麻烦告诉我,感谢。
真正需要校正的畸变,目前看只有径向畸变。
总结:畸变这个话题看来还是有一些不解的地方,知道的朋友请不吝赐教!
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!

