Cruise007
论坛版主
论坛版主
  • 最后登录2020-10-19
  • 发帖数100
  • 金币4145枚
  • 贡献勋章0枚
  • 原创写手
  • 喜欢达人
  • 社区居民
  • 忠实会员
阅读:11579回复:36

相机标定-畸变校正

楼主#
更多 发布于:2018-06-06 11:59


1 halcon相机标定和图像矫正

对于相机采集的图片,会由于相机本身和透镜的影响产生形变,通常需要对相机进行标定,获取相机的内参或内外参,然后矫正其畸变。相机畸变主要分为径向畸变和切向畸变,其中径向畸变是由透镜造成的,切向畸变是由成像仪与相机透镜的不平行造成的。
针孔模型是理想透镜的成像模型,但是实际中相机的透镜不可能是理想的模型,透镜形状的非理想特征造成像点会沿径向发生畸变。一个像点沿径向内缩叫负畸变或桶形畸变沿径向外延叫正畸变或枕形畸变。这种崎变相对于光轴严格对称的也是畸变的主要分量

1径向畸变                           图2切向畸变
相机标定模型公式,
                 Or                                                                     (1-1)
其中,(X,Y,Z)为世界坐标系中的实际点坐标,(u,v)为图像坐标系统的像素坐标,A为相机内参,f像素单元的焦距,c图像像素中心点。
                                                 (1-2)
3相机成像模型


1.1 halcon相机标定



1.1.1标定助手及相机参数设置

打开halcon标定助手,加载标定板文件,选择相机类型,设置相机参数,然后加载相机采集的标定图像,如下图所示,图像中全部标定点能够检测出,即采集的相机已经设置好,然后生成代码。
4 halcon标定助
标定板生成:
标定板文件的生成分为.descr.cpd的文件,不同格式文件需使用不同函数进行生成。如,
*生成的是27*31,标定点直径0.0075mm的.cpd标定板(精度高标定板)
create_caltab (27, 31, 0.0075, [13, 6, 6, 20, 20], [15, 6, 24, 6, 24], 'light_on_dark', 'D:/calplate.cpd', 'caltab.ps')
*生成的是7*7,标定点之间距离0.1m,直径0.5的.descr标定板
gen_caltab( 7, 7, 0.1, 0.5, 'D:/caltab.descr', 'caltab.ps')
加载标定图像:
5加载标定图像
如图5所示,加载标定图像后,状态为确定时,表示标定图像可用于进行标定,然后通过标定助手直接生成标定代码即可。
   如图6所示,加载标定图像后,状态为检测出品质问题,此原因大多是照片质量问题,例如光照、对焦、曝光等,需按照halcon标定注意事项的内容拍摄照片。一般照片检测出品质问题也可以进行相机标定。
加载标定板图像会出现“标志点提取失败”,出现此原因的需要根据标定界面下的状态栏查找halcon错误信息,例inconsistent....(image mirrored? ),则需要查找相应原因(实际标定板(透明)与标定板文件图片的可能有镜像区别,将实际标定板翻转即可,多试)。此不可进行相机标定。
                           
图6 相机标定问题
相机初始参数设置:
例如,
*(f, k, cell width, cell height, cx, cy, width, height)k为畸变系数
StartParameters := [0.029,0,4.3e-006,4.3e-006,2592,1728,5184,3456]
*(f, k1, k2, k3, p1, p2, cell width, cell height, cx, cy, width, height)k1,k2,k3径向畸变, p1,p2为切向畸变
StartParameters := [0.029,0,0,0,0,0,4.3e-006,4.3e-006,2592,1728,5184,3456]
其中,相机初始参数根据相机模型的不同而不同,若相机模型为area(division),则相机参数为7个,若area(多项式),则相机参数12个。


1.1.2 标定程序

利用标定助手生成代码,然后执行结果,分析其正确性,若需要将其生成为C/C++程序,可通过halcon界面的‘文件’项‘导出’成.cpp文件。
图7 halcon生成C程序
Halcon标定程序
*Calibration 01: Code generated by Calibration 01
*读入某个文件夹下的所有标定图像
list_files ('D:/halconvc/img', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm
|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
*初始标定参数设置及定义标定板文件
TmpCtrl_ReferenceIndex := 0
TmpCtrl_PlateDescription := 'D:/calib/calplate.cpd'
StartParameters := [0.029,0,0,0,0,0,4.3e-006,4.3e-006,2592,1728,5184,3456]
TmpCtrl_FindCalObjParNames := 'sigma'
TmpCtrl_FindCalObjParValues := 1

* Calibration 01: Create calibration model for managing calibration data
create_calib_data ('calibration_object', 1, 1, CalibHandle)
set_calib_data_cam_param(CalibHandle,0,'area_scan_polynomial', StartParameters)
set_calib_data_calib_object (CalibHandle, 0, TmpCtrl_PlateDescription)
* Calibration 01: Collect mark positions and estimated poses for all plates
gen_empty_obj (Images)
for Index := 0 to |ImageFiles|-1 by 1
   read_image (Image, ImageFiles[Index])
   concat_obj(Images,Image,Images)
*提取图像Images中标定板上的圆形标志来确定标定板的有效区域
   find_calib_object (Image, CalibHandle, 0, 0, Index, TmpCtrl_FindCalObjParNames, TmpCtrl_FindCalObjParValues)
endfor
* Calibration 01: Perform the actual calibration
calibrate_cameras (CalibHandle, TmpCtrl_Errors)
get_calib_data (CalibHandle, 'camera', 0, 'params', CameraParam)

 *将内外参保存到磁盘
write_cam_par(CameraParam,'D:/halconvc/campar.dat')
get_calib_data (CalibHandle, 'calib_obj_pose', [0, TmpCtrl_ReferenceIndex], 'pose', CameraPose)
set_origin_pose (CameraPose, 0, 0, 0.01, CameraPose)
write_pose(CameraPose,'D:/halconvc/campos.dat')
stop()

*另外读取内外参文件的函数
read_cam_par ('D:/halconvc/campar.dat', CameraParam)
read_pose ('D:/halconvc/campos.dat', CameraPose)


1.2图像矫正

Halcon中图像矫正,接上述程序,以下介绍两种方法。
使用内外参,即相机内参和位资
*  goal: rectify images
*  first determine parameters such that the entire image content is visible
*  -> transform image boundary into world plane, determine smallest
*     rectangle around it
*当设备固定后,位资是唯一的
select_obj(images,image,1)
get_image_pointer1(Image, Pointer, Type, Width, Height)
gen_rectangle1 (ImageRect, 0, 0, Height-1, Width-1)
gen_contour_region_xld (ImageRect, ImageBorder, 'border')
contour_to_world_plane_xld(ImageBorder, ImageBorderWCS, CameraParam,
CameraPose, 1)
smallest_rectangle1_xld (ImageBorderWCS, MinY, MinX, MaxY, MaxX)
set_origin_pose(CameraPose, MinX, MinY, 0.01, PoseForEntireImage)
image_points_to_world_plane(CameraParam,PoseForEntireImage,[Height/2, Height/2, Height/2+1], [Width/2, Width/2+1, Width/2], 1, WorldPixelX, WorldPixelY)
distance_pp(WorldPixelY[0], WorldPixelX[0], WorldPixelY[1], WorldPixelX[1],
           WorldLength1)
distance_pp(WorldPixelY[0], WorldPixelX[0], WorldPixelY[2], WorldPixelX[2],
           WorldLength2)
ScaleForSimilarPixelSize := (WorldLength1+WorldLength2)/2
*  -> determine output image size such that entire input image fits into it
ExtentX := MaxX-MinX
ExtentY := MaxY-MinY
WidthRectifiedImage := ExtentX/ScaleForSimilarPixelSize
HeightRectifiedImage := ExtentY/ScaleForSimilarPixelSize
*  create mapping with the determined parachuangjia
*创建一个投射图,其描述图像平面与坐标轴系统中平面Z为零之间的映射
gen_image_to_world_plane_map(Map, CameraParam, PoseForEntireImage, Width, Height, WidthRectifiedImage, HeightRectifiedImage, \
                            ScaleForSimilarPixelSize, 'bilinear')
clear_calib_data (CalibHandle)

* Map the images
for I :=  1 to |ImageFiles| by 1
 select_obj (Images, Img, I)
 map_image (Img, Map, ImageMapped)
 write_image (ImageMapped, 'jpg', 0, 'D:/halconvc/picture/'+I)
Endfor
②仅使用内参
read_image (Image,'D:/halconvc/img/IMG_00.JPG')
read_cam_par('D:/halconvc/campar.dat',CameraParam)
CarParamVirtualFixed:=CameraParam
*对于area(diversion)相机模型(7个参数)
change_radial_distortion_cam_par('adaptive',CameraParam,0,CarParamVirtualFixed)
*对于area(多项式)相机模型(12个参数)
change_radial_distortion_cam_par('adaptive',CameraParam,[0,0,0,0,0],CarParamVirtualFixed)


*上述相机模型选一种后进行下面的map_image
*创建一个投射图,其描述图像与其相应正在改变的径向畸变,而对于12个参数的畸变包括径向和切向畸变
gen_radial_distortion_map(Map,CameraParam,CarParamVirtualFixed,'bilinear')
map_image(Image,Map,ImageMapped)
喜欢8

最新打赏:0人

努力到无能为力,拼搏到感动自己
zmfcyj
初学者
初学者
  • 最后登录2020-09-10
  • 发帖数7
  • 金币75枚
  • 贡献勋章0枚
  • 社区居民
沙发#
发布于:2018-07-10 17:04
学习一下,图片怎么显示不了。
sj461475691
初学者
初学者
  • 最后登录2020-10-18
  • 发帖数205
  • 金币61枚
  • 贡献勋章0枚
  • 社区居民
  • 忠实会员
板凳#
发布于:2018-07-10 21:42
你好,咨询下,我相机标定后还是有较大的畸变。麻烦问下你实际项目标定一定要标定外参么?
奔跑的小猪
初学者
初学者
  • 最后登录2020-08-07
  • 发帖数44
  • 金币86枚
  • 贡献勋章0枚
地板#
发布于:2018-07-27 17:29
看看,僚机   了解下!!!!!!!!!!!!!!!!!!!!!!
cjy1119295968
助理工程师
助理工程师
  • 最后登录2020-10-20
  • 发帖数306
  • 金币1218枚
  • 贡献勋章0枚
  • 社区居民
  • 忠实会员
4楼#
发布于:2018-08-27 07:03
学习。。。。。。。。。。。。。。。
gpf200858
技术员
技术员
  • 最后登录2020-10-20
  • 发帖数109
  • 金币709枚
  • 贡献勋章0枚
  • 社区居民
  • 忠实会员
5楼#
发布于:2018-09-19 18:43
同样的问题, 我这边打开之后也是不现实图片
834825501
初学者
初学者
  • 最后登录2020-10-15
  • 发帖数197
  • 金币30枚
  • 贡献勋章0枚
  • 社区居民
  • 忠实会员
6楼#
发布于:2018-09-29 12:05
正好做项目需要标定 学习一下
gpf200858
技术员
技术员
  • 最后登录2020-10-20
  • 发帖数109
  • 金币709枚
  • 贡献勋章0枚
  • 社区居民
  • 忠实会员
7楼#
发布于:2018-10-07 09:23
学习一下,但时图片确实时显示不了了
wtmwtmwtmwtm
技术员
技术员
  • 最后登录2019-11-19
  • 发帖数18
  • 金币154枚
  • 贡献勋章0枚
  • 社区居民
8楼#
发布于:2018-11-21 11:36
想认真学习一下,可是看不到图片
fenghuo521
技术员
技术员
  • 最后登录2020-10-15
  • 发帖数409
  • 金币804枚
  • 贡献勋章0枚
  • 社区居民
9楼#
发布于:2019-01-09 17:08
学习一下,图片怎么显示不了。
大大大大胜
技术员
技术员
  • 最后登录2019-02-23
  • 发帖数38
  • 金币145枚
  • 贡献勋章0枚
  • 社区居民
10楼#
发布于:2019-01-10 08:13
6666666666666666666666666
Yates
技术员
技术员
  • 最后登录2020-01-17
  • 发帖数232
  • 金币475枚
  • 贡献勋章0枚
  • 社区居民
  • 忠实会员
11楼#
发布于:2019-06-03 22:09
学习一下,但是看不到图片
caicai1001
技术员
技术员
  • 最后登录2020-10-20
  • 发帖数356
  • 金币988枚
  • 贡献勋章0枚
  • 社区居民
  • 忠实会员
12楼#
发布于:2019-06-27 13:58
mark@@@@@@@@@@@@@
h312902013
初学者
初学者
  • 最后登录2019-07-24
  • 发帖数18
  • 金币71枚
  • 贡献勋章0枚
  • 社区居民
13楼#
发布于:2019-07-10 10:18
学习一下,但是看不到图片
lianzaozi
技术员
技术员
  • 最后登录2020-09-22
  • 发帖数213
  • 金币179枚
  • 贡献勋章0枚
  • 社区居民
  • 忠实会员
14楼#
发布于:2019-07-13 09:48
学习一下,图片怎么显示不了。
学习一下,图片怎么显示不了。
上一页
游客

返回顶部
支付

欢迎打赏,请选择打赏金额

  • 1元
  • 6元
  • 10元
  • 66元
  • 100元

支付即代表同意《本站支付协议》 有疑问请联系客服