当前位置: 首页 > news >正文

13:图像处理—畸变矫正详解

1.制作标定板和描述文件

(用PS软件打印)

*  0.00375 mark 点间距  , 不是 点的直径//倒数第二个就是描述文件
gen_caltab(7,7,0.00375,0.5,'caltab_30mm.descr','30-30.ps')
* 1  比 1 打印  。Photoshop 格式

2.把标定板调正

调正的目的是为了确定一个正中心的参考姿态(放在循环读取标定图像之后,获取外参的基准)

方法一:

*实时调整 相机视野内的标定板中心点的位置和角度 。 角度 保持在0度 ±4度。  位置在中心点 600,800  ±3.
*************************************************************1.初始化******************************************************************************
* 关闭窗口
dev_close_window ()
* 更新程序计数器,更新变量,更新图形窗口
dev_update_off ()
* 设置区域填充模式
dev_set_draw ('margin')
* 读取图像
read_image (Image, './图像/1.bmp')
* 获取图像类型,宽度,高度,缓存数据get_image_pointer1 (Image, Pointer, Type, Width, Height)
* 打开窗口
dev_open_window (0, 0, Width/5, Height/5, 'black', WindowHandle1)
* 设置字体信息
set_display_font (WindowHandle1, 14, 'mono', 'true', 'false')
* 显示图像
dev_display (Image)
get_image_size(Image, Width, Height)
* 右下角显示运行字样字符串
disp_continue_message (WindowHandle1, 'black', 'true')
* 
*************************************************************2.校正相机****************************************************************************
* 标定文件名
CaltabName := 'caltab_30mm.descr'
* [Focus,Kappa,Sx,Sy,Cx,Cy,Width,Height]
*Focus  镜头的焦距
*Kappa  畸变值
*Sx,Sy  像元尺寸  4.8 0.0000048  =4.8 *e-6  m
*Cx 640, Cy 512
*Width,Height  1280,1024
*3072  2048
StartCamPar := [0.008,0,2.4e-006,2.4e-006,3072/2,1024,3072,2048]*创建标定数据模型
*CalibDataID   准备一个标定句柄!
create_calib_data ('calibration_object', 1, 1, CalibDataID)*1.设置相机类型并初始化标定数据模型里的摄像机内部参数
*面扫描 多项式  area_scan_division
set_calib_data_cam_param (CalibDataID, 0, \'area_scan_division', StartCamPar)
*2.为校正句柄 指定校正文件  'caltab_30mm.descr'
set_calib_data_calib_object (CalibDataID, 0, CaltabName)*读取图像
read_image (Image1, './图像/1.bmp')
*图像增强
scale_image(Image1, Image, 1.0, 0)
*显示图像
dev_display (Image)
*获取校正板内边框以内的区域
find_caltab (Image, Caltab, CaltabName, 3, 110, 5)
*设置输出对象显示颜色
dev_set_color ('green')
*显示校正板内边框以内的区域
dev_display (Caltab)
*提取出图像中MARK点的位置并计算出摄像机外部参数
find_marks_and_pose (Image, Caltab, CaltabName, StartCamPar,\128, 10, 18, 0.9, 15, 100, \RCoord, CCoord, StartPose)*设置输出对象显示颜色
dev_set_color ('red')
*设置半径为2.5
tuple_gen_const(|RCoord|,2.5, Radius)
*显示MARK所有点的位置disp_circle (WindowHandle1, RCoord, CCoord, Radius)
dev_set_color ('blue')
*显示MARK中心点的位置
disp_circle (WindowHandle1, RCoord[24], CCoord[24], 6)*设置第一行的起始点和终点
StartRow:=RCoord[0]
StartColumn:=CCoord[0]
EndRow:=RCoord[6]
EndColumn:=CCoord[6]
dev_set_color('yellow')*设置第一行的所有点
Row:=[]
Column:=[]
Row:=RCoord[0:6]
Column:=CCoord[0:6]
stop()
*显示第一行的所有点
gen_cross_contour_xld(Cross, Row, Column, 6, 0.785398)dev_set_line_width(3)
dev_set_color('red')
*由点生成直线
gen_contour_polygon_xld (Contour, Row, Column)*拟合直线
fit_line_contour_xld (Contour, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)*生成直线
gen_contour_polygon_xld (Contour, [RowBegin,RowEnd], [ColBegin,ColEnd])*显示直线起点
disp_circle (WindowHandle1, RCoord[0], CCoord[0], 6)
*显示终点
disp_circle (WindowHandle1, RCoord[6], CCoord[6], 6)*计算直线角度
angle_lx(RowBegin,ColBegin,RowEnd,ColEnd,Phi)Angle:=deg(Phi)
disp_message (WindowHandle1, 'RCoord= '+RCoord[24], ' WindowHandle', RCoord[24], CCoord[24], 'yellow', 'false')
disp_message (WindowHandle1,'CCoord= '+CCoord[24], ' WindowHandle', RCoord[24]+40, CCoord[24], 'yellow', 'false')
disp_message (WindowHandle1, 'angle= '+Angle, 'WindowHandle', RCoord[0], CCoord[0], 'red', 'false') 
dev_update_time ('on')
disp_continue_message (WindowHandle1, 'black', 'true')*移动到中心点(仿射变换)
get_image_size(Image, Width1, Height1)
vector_angle_to_rigid(RCoord[24], CCoord[24], rad(Angle), Height1/2, Width1/2, 0, HomMat2D)
affine_trans_image(Image, ImageAffinTrans, HomMat2D, 'constant', 'false')*保存调正的图像
write_image(ImageAffinTrans, 'bmp', 0, 'TZ11')
stop ()

方法二:

*实时调整 相机视野内的标定板中心点的位置和角度 。 角度 保持在0度 ±4度。  位置在中心点 600,800  ±3.
*************************************************************1.初始化******************************************************************************
* 关闭窗口
dev_close_window ()
* 更新程序计数器,更新变量,更新图形窗口
dev_update_off ()
* 设置区域填充模式
dev_set_draw ('margin')
* 读取图像
read_image (Image, 'pic02.png')
* 获取图像类型,宽度,高度,缓存数据
get_image_pointer1 (Image, Pointer, Type, Width, Height)
* 打开窗口
dev_open_window (0, 0, Width/2, Height/2, 'black', WindowHandle1)
* 设置字体信息
set_display_font (WindowHandle1, 14, 'mono', 'true', 'false')
* 显示图像
dev_display (Image)
* 右下角显示运行字样字符串
disp_continue_message (WindowHandle1, 'black', 'true')
* 
*************************************************************2.校正相机****************************************************************************
* 标定文件名
CaltabName := 'caltab_56mm.descr'
* [Focus,Kappa,Sx,Sy,Cx,Cy,Whith,Height]
StartCamPar := [0.0184898,-548.002,8.33409e-006,8.3e-006,275.291,255.374,1600,1200]
*创建标定数据模型
create_calib_data ('calibration_object', 1, 1, CalibDataID)
*设置相机类型并初始化标定数据模型里的摄像机内部参数
set_calib_data_cam_param (CalibDataID, 0, 'area_scan_division', StartCamPar)
*为校正模型指定校正文件
set_calib_data_calib_object (CalibDataID, 0, CaltabName)
*读取图像
read_image (Image, 'pic02.png')
*显示图像
dev_display (Image)
*获取校正板内边框以内的区域
find_caltab (Image, Caltab, CaltabName, 3, 112, 5)
*设置输出对象显示颜色
dev_set_color ('green')
*显示校正板内边框以内的区域
dev_display (Caltab)
*提取出图像中MARK点的位置并计算出摄像机外部参数
find_marks_and_pose (Image, Caltab, CaltabName, StartCamPar, 128, 10, 18, 0.9, 15, 100, RCoord, CCoord, StartPose)
*设置输出对象显示颜色
dev_set_color ('red')
*显示MARK点的位置
disp_circle (WindowHandle1, RCoord, CCoord, gen_tuple_const(|RCoord|,2.5))
dev_set_color ('blue')
*显示MARK点的位置
disp_circle (WindowHandle1, RCoord[24], CCoord[24], 6)
StartRow:=RCoord[0]
StartColumn:=CCoord[0]
EndRow:=RCoord[6]
EndColumn:=CCoord[6]
dev_set_color('yellow')
Row:=[]
Column:=[]
for i:=0 to 6 by 1
Row:=[Row,RCoord[i]]
Column:=[ Column,CCoord[i]]
endfor   
stop()
gen_cross_contour_xld(Cross, Row, Column, 6, 0.785398)
gen_contour_polygon_xld (Contour, Row, Column)
fit_line_contour_xld (Contour, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)
gen_contour_polygon_xld (Contour, [RowBegin,RowEnd], [ColBegin,ColEnd])
disp_circle (WindowHandle1, RCoord[0], CCoord[0], 6)
disp_circle (WindowHandle1, RCoord[6], CCoord[6], 6)
angle_lx(RowBegin,ColBegin,RowEnd,ColEnd,Phi)
Angle:=Phi*180/3.1415926
disp_message (WindowHandle1, 'RCoord= '+RCoord[24], ' WindowHandle', RCoord[24], CCoord[24], 'yellow', 'false')
disp_message (WindowHandle1,'CCoord= '+CCoord[24], ' WindowHandle', RCoord[24]+40, CCoord[24], 'yellow', 'false')
disp_message (WindowHandle1, 'angle= '+Angle, 'WindowHandle', RCoord[0], CCoord[0], 'red', 'false') 
dev_update_time ('on')
disp_continue_message (WindowHandle1, 'black', 'true')*移动到中心点
get_image_size(Image, Width1, Height1)
vector_angle_to_rigid(RCoord[24], CCoord[24], rad(Angle), Height1/2, Width1/2, 0, HomMat2D)
affine_trans_image(Image, ImageAffinTrans, HomMat2D, 'constant', 'false')write_image(ImageAffinTrans, 'png', 0, 'pic06.png')
stop ()

3.内外参标定

* 关闭窗口
dev_close_window ()
* 更新程序计数器,更新变量,更新图形窗口
dev_update_off ()
* 设置区域填充模式
dev_set_draw ('margin')
* 读取图像
read_image (Image, 'MPic/pic01.png')
* 获取图像类型,宽度,高度,缓存数据
get_image_pointer1 (Image, Pointer, Type, Width, Height)
* 打开窗口
dev_open_window (0, 0, Width/2, Height/2, 'black', WindowHandle1)
* 设置字体信息
set_display_font (WindowHandle1, 14, 'mono', 'true', 'false')
* 显示图像
dev_display (Image)
* 右下角显示运行字样字符串
disp_continue_message (WindowHandle1, 'black', 'true')
stop ()* 标定文件名
CaltabName := 'caltab_56mm.descr'
* [Focus,Kappa,Sx,Sy,Cx,Cy,Width,Height]
StartCamPar := [0.008, 0, 5.2e-006, 5.2e-006, 800, 600, 1600, 1200]
*创建标定数据模型
create_calib_data ('calibration_object', 1, 1, CalibDataID)
*设置相机类型并初始化标定数据模型里的摄像机内部参数
set_calib_data_cam_param (CalibDataID, 0, 'area_scan_division', StartCamPar)
*为校正模型指定校正文件
set_calib_data_calib_object (CalibDataID, 0, CaltabName)
NumImages := 8
for i := 0 to NumImages by 1*读取图像read_image (Image, 'MPic/pic'+(i+1)$'02d')*显示图像dev_display (Image)gen_rectangle1(Rectangle, 1, 1, 1200,1600)reduce_domain(Image, Rectangle, ImageReduced1)min_max_gray ( ImageReduced1, Image, 5, Min, Max, Range)scale_image (Image, ImageScaled, 255 / Range, -Min * 255 / Range)*获取校正板内边框以内的区域find_caltab (ImageScaled, Caltab, CaltabName, 3, 112, 5)*设置输出对象显示颜色dev_set_color ('green')*显示校正板内边框以内的区域dev_display (Caltab)*提取出图像中MARK点的位置并计算出摄像机外部参数find_marks_and_pose (Image, Caltab, CaltabName, StartCamPar, \128, 10, 18, 0.9, 15, 100, RCoord, CCoord, StartPose)*设置输出对象显示颜色dev_set_color ('red')*显示MARK点的位置disp_circle (WindowHandle1, RCoord, CCoord, gen_tuple_const(|RCoord|,2.5))dev_set_part (0, 0, Height-1, Width-1)*收集观察数据set_calib_data_observ_points (CalibDataID, 0, 0, i, RCoord, CCoord, 'all', StartPose)
endfor
dev_update_time ('on')
disp_continue_message (WindowHandle1, 'black', 'true')
stop ()
*开始校正摄像机
calibrate_cameras (CalibDataID, Error)
*获取优化以后的摄像机内部参数
get_calib_data (CalibDataID, 'camera', 0, 'params', CamParam)
******保存相机内参,且该函数只能保存内参***
write_cam_par(CamParam,'cam.dat')
****************************
*获取优化以后的校正对象姿势,相对于当前参考相机。(这个位姿就是上面调正后的标定板位姿)
get_calib_data (CalibDataID, 'calib_obj_pose', [0,0], 'pose', PoseCalib)
write_pose(PoseCalib, 'poseOrigin.dat')

4.单像素对应的距离

*矫正后再测量
*选取两个像素点  2个点求距离
Image_X1:=100
Image_Y1:=100Distance_XY:=500
Image_X2:=Image_X1+Distance_XY
Image_Y2:=Image_Y1+Distance_XYgen_cross_contour_xld(Cross1, Image_X1, Image_Y1, 46, 0.785398)
gen_cross_contour_xld(Cross2, Image_X2, Image_Y2, 76, 0.785398)
*考虑标定板厚度的影响  PoseNewOrigin在这里
*[0.0209422, -0.0257558, 0.56891, 7.69086, 10.9034, 359.249, 0]* 0  旋转轴种类
* pose1:=[0,0,0.003,0,0,0,0]
* pose_compose(PoseCalib,pose1,PoseCompose1)* 0.003  标定板的厚度  3mm  0.003m  
*第一个参数是标定的外参
set_origin_pose(PoseCalib,0,0,-0.003,PoseNewOrigin)*将像素坐标转化为世界坐标(单位m)第一个参数是标定的内参
image_points_to_world_plane(CamParam, PoseNewOrigin, Image_Y1, Image_X1, 'm', World_X1, World_Y1)
image_points_to_world_plane(CamParam ,PoseNewOrigin, Image_Y2, Image_X2, 'm', World_X2, World_Y2)*******************************************************************************************
*计算世界坐标距离
distance_pp(World_Y1, World_X1, World_Y2, World_X2, DistanceWorld)
*计算像素坐标
distance_pp(Image_X1,Image_Y1,Image_X2,Image_Y2,DistanceImage)*每个像素对应的世界坐标距离
DistanceOnePixel:=DistanceWorld/DistanceImage

5.求偏移值,把图像移到正中间

WindowHandle1Out := WindowHandle1disp_3d_coord_system (WindowHandle1Out, CamParam, PoseNewOrigin, 0.05)*调整世界坐标到中心偏移量
OffSetX:=(Width/2)*DistanceOnePixel
OffSetY:=(Height/2)*DistanceOnePixelset_origin_pose (PoseNewOrigin, -OffSetX, -OffSetY, 0, PoseNewOriginFinal)

6.消除畸变和视角畸变

*内参 CamParam, 
* 外参 PoseNewOriginFinal, 
*图像的宽度和高度, 像素Width, Height, Width, Height,
*单像素对应距离DistanceOnePixelgen_image_to_world_plane_map(Map1, CamParam, PoseNewOriginFinal, Width, Height, \Width, Height,DistanceOnePixel, 'bilinear')write_object(Map1, 'Map1.obj')read_object(Map1, 'Map1.obj')
*5.验证 和  测试 !
for Index := 1 to 1 by 1read_image(Image1, 'MPic/pic'+Index$'02d'+'.png')* 在这里对原始图像 Image1, 进行畸变矫正,ImageMapped1。map_image(Image1,Map1, ImageMapped1)*验证精度是否足够dev_open_window (0, 0, Width/2, Height/2, 'black', WindowHandle3)dev_display(ImageMapped1)column:=611dev_set_color('blue')dev_set_line_width(3)gen_contour_polygon_xld (Polygon, [451,451], [column,column+0.056/DistanceOnePixel])dev_set_color('red')dev_set_line_width(1)gen_cross_contour_xld(Cross1, 451, column, 46, 0.785398)gen_cross_contour_xld(Cross2, 451, column+0.056/DistanceOnePixel, 46, 0.785398)disp_message (WindowHandle3, '56cm', 'window', 205, 195, 'red', 'false')dev_display (Polygon)dev_display (Cross1)dev_display (Cross2)disp_continue_message (WindowHandle3, 'black', 'true')stop()
endfor



附录

* This program measures the length of scratches in world
* coordinates in a perspectively distorted image
*************************************************************1.初始化******************************************************************************
* 关闭窗口
dev_close_window ()
* 更新程序计数器,更新变量,更新图形窗口
dev_update_off ()
* 设置区域填充模式
dev_set_draw ('margin')
* 读取图像
read_image (Image, 'picture/image1.png')
* 获取图像类型,宽度,高度,缓存数据
get_image_pointer1 (Image, Pointer, Type, Width, Height)
* 打开窗口
dev_open_window (0, 0, Width/2, Height/2, 'black', WindowHandle1)
* 设置字体信息
set_display_font (WindowHandle1, 14, 'mono', 'true', 'false')
* 显示图像
dev_display (Image)
* 右下角显示运行字样字符串
disp_continue_message (WindowHandle1, 'black', 'true')
stop ()
* 
*************************************************************2.校正相机****************************************************************************
*   read_cam_par ('cam.dat', CamParam)* 标定文件名
CaltabName := 'caltab_56mm.descr'
* [Focus,Kappa,Sx,Sy,Cx,Cy,Whith,Height]
StartCamPar := [0.008, 0, 5.2e-006, 5.2e-006, 640, 512, 1280, 1024]
*创建标定数据模型
create_calib_data ('calibration_object', 1, 1, CalibDataID)
*设置相机类型并初始化标定数据模型里的摄像机内部参数
set_calib_data_cam_param (CalibDataID, 0, 'area_scan_division', StartCamPar)
*为校正模型指定校正文件
set_calib_data_calib_object (CalibDataID, 0, CaltabName)
NumImages := 8
for i := 1 to NumImages by 1*读取图像read_image (Image, 'picture/image'+i$'01d')*显示图像dev_display (Image)gen_rectangle1(Rectangle, 1, 1, 1024,1280)reduce_domain(Image, Rectangle, ImageReduced1)min_max_gray ( ImageReduced1, Image, 5, Min, Max, Range)scale_image (Image, ImageScaled, 255 / Range, -Min * 255 / Range)*获取校正板内边框以内的区域find_caltab (ImageScaled, Caltab, CaltabName, 3, 112, 5)*设置输出对象显示颜色dev_set_color ('green')*显示校正板内边框以内的区域dev_display (Caltab)*提取出图像中MARK点的位置并计算出摄像机外部参数find_marks_and_pose (Image, Caltab, CaltabName, StartCamPar, 128, 10, 18, 0.9, 15, 100, RCoord, CCoord, StartPose)*设置输出对象显示颜色dev_set_color ('red')*显示MARK点的位置disp_circle (WindowHandle1, RCoord, CCoord, gen_tuple_const(|RCoord|,2.5))dev_set_part (0, 0, Height-1, Width-1)*收集观察数据set_calib_data_observ_points (CalibDataID, 0, 0, i, RCoord, CCoord, 'all', StartPose)
endfor
dev_update_time ('on')
disp_continue_message (WindowHandle1, 'black', 'true')
stop ()
*开始校正摄像机
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,'cam.dat')
write_pose(PoseCalib, 'poseOrigin.dat')stop()*都是两个点求距离************************************************************************************************************************矫正后再测量
*选取两个像素点  2个点求距离
Image_X1:=100
Image_Y1:=100
Distance_XY:=500
Image_X2:=Image_X1+Distance_XY
Image_Y2:=Image_Y1+Distance_XY*考虑标定板厚度的影响  PoseNewOrigin在这里set_origin_pose(PoseCalib,0,0,0.003,PoseNewOrigin)
*将像素坐标转化为世界坐标(单位m)
image_points_to_world_plane(CamParam, PoseNewOrigin, Image_Y1, Image_X1, 'm', World_X1, World_Y1)
image_points_to_world_plane(CamParam ,PoseNewOrigin, Image_Y2, Image_X2, 'm', World_X2, World_Y2)*******************************************************************************************
*计算世界坐标距离
distance_pp(World_Y1, World_X1, World_Y2, World_X2, DistanceWorld)
*计算像素坐标
distance_pp(Image_X1,Image_Y1,Image_X2,Image_Y2,DistanceImage)*每个像素对应的世界坐标距离
DistanceOnePixel:=DistanceWorld/DistanceImage
*调整世界坐标到中心偏移量
OffSetX:=(Width/2)*DistanceOnePixel
OffSetY:=(Height/2)*DistanceOnePixel*
*************************************************************3.图像转换****************************************************************************
*这张图  是 世界坐标系的参考姿态图   ,与外参demo  中游标卡尺的坐标系是类似的作用
read_image (ImagePespective, 'picture/image1.png')
*调整相机外参
*假如需要重新拍一张图 ,这个图 与世界坐标系 的姿态一致。由于是平面,不考虑  x  y  的变化,只考虑z方向角度的变化。
*所以这里是第5个值 需要替换 ,RZ
*PoseCalibRot 是机器人的坐标系
* tuple_replace (PoseNewOrigin, 5, PoseCalib[5], PoseCalibRot)
********************************************************************************************将摄像机位姿进行X,Y,Z的平移(矩阵乘积)  设定世界坐标
set_origin_pose (PoseNewOrigin, -OffSetX, -OffSetY, 0, PoseNewOriginFinal)
*生成map,消除径向畸变和视角畸变
gen_image_to_world_plane_map(Map1, CamParam, PoseNewOriginFinal, Width, Height, Width, Height,DistanceOnePixel, 'bilinear')
write_object(Map1, 'Map1.obj')
*矫正图像
map_image(ImagePespective,Map1, ImageMapped1)
dev_open_window (0, 0, Width/2, Height/2, 'black', WindowHandle3)
dev_display(ImageMapped1)
column:=511
*0.00021932gen_contour_polygon_xld (Polygon, [451,451], [column,column+0.056/DistanceOnePixel])
dev_set_color('blue')
gen_cross_contour_xld(Cross, 451, column, 16, 0.785398)disp_message (WindowHandle3, '56cm', 'window', 205, 195, 'red', 'false')dev_display (Polygon)disp_continue_message (WindowHandle3, 'black', 'true')
stop()









详细完整步骤:

  调平角度的目的是为了设定一个正中心的标定板外参位姿为参考

*实时调整 相机视野内的标定板中心点的位置和角度 。 角度 保持在0度 ±4度。  位置在中心点 600,800  ±3.
*************************************************************1.初始化******************************************************************************
* 关闭窗口
dev_close_window ()
* 更新程序计数器,更新变量,更新图形窗口
dev_update_off ()
* 设置区域填充模式
dev_set_draw ('margin')
* 读取图像
read_image (Image, './图片/1')
* 获取图像类型,宽度,高度,缓存数据
get_image_size(Image, Width, Height)
* get_image_pointer1 (Image, Pointer, Type, Width, Height)
* 打开窗口
dev_open_window (0, 0, Width/2, Height/2, 'black', WindowHandle1)
* 设置字体信息
set_display_font (WindowHandle1, 14, 'mono', 'true', 'false')
* 显示图像
dev_display (Image)
* 右下角显示运行字样字符串
disp_continue_message (WindowHandle1, 'black', 'true')
* 
*************************************************************2.校正相机****************************************************************************
* 标定文件名
CaltabName := 'caltab_30mm.descr'
* [Focus,Kappa,Sx,Sy,Cx,Cy,Whith,Height]*  焦距   初始畸变   像元尺寸  中心点  图像的宽 和 高
StartCamPar := [0.008,0,4.8e-006,4.8e-006,640,512,1280,1024]
*创建标定数据模型
create_calib_data ('calibration_object', 1, 1, CalibDataID)
*设置相机类型并初始化标定数据模型里的摄像机内部参数
set_calib_data_cam_param (CalibDataID, 0, 'area_scan_division', StartCamPar)
*为校正模型指定校正文件
set_calib_data_calib_object (CalibDataID, 0, CaltabName)*读取图像
read_image (Image, './图片/1')
*显示图像
dev_display (Image)
*获取校正板内边框以内的区域
find_caltab (Image, Caltab, CaltabName, 3, 112, 5)
*设置输出对象显示颜色
dev_set_color ('green')
*显示校正板内边框以内的区域
dev_display (Caltab)
*提取出图像中MARK点的位置并计算出摄像机外部参数
find_marks_and_pose (Image, Caltab, CaltabName, StartCamPar, 128, 10, 18, 0.9, 15, 100, RCoord, CCoord, StartPose)
*设置输出对象显示颜色
dev_set_color ('red')
*显示MARK点的位置
disp_circle (WindowHandle1, RCoord, CCoord, gen_tuple_const(|RCoord|,2.5))
dev_set_color ('blue')
*显示MARK点的位置
disp_circle (WindowHandle1, RCoord[24], CCoord[24], 6)
StartRow:=RCoord[0]
StartColumn:=CCoord[0]
EndRow:=RCoord[6]
EndColumn:=CCoord[6]
dev_set_color('yellow')
Row:=[]
Column:=[]for i:=0 to 6 by 1
Row:=[Row,RCoord[i]]
Column:=[ Column,CCoord[i]]
endfor   
stop()
gen_cross_contour_xld(Cross, Row, Column, 6, 0.785398)
gen_contour_polygon_xld (Contour, Row, Column)
fit_line_contour_xld (Contour, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)
gen_contour_polygon_xld (Contour, [RowBegin,RowEnd], [ColBegin,ColEnd])
disp_circle (WindowHandle1, RCoord[0], CCoord[0], 6)
disp_circle (WindowHandle1, RCoord[6], CCoord[6], 6)
angle_lx(RowBegin,ColBegin,RowEnd,ColEnd,Phi)
Angle:=Phi*180/3.1415926
disp_message (WindowHandle1, 'RCoord= '+RCoord[24], ' WindowHandle', RCoord[24], CCoord[24], 'yellow', 'false')
disp_message (WindowHandle1,'CCoord= '+CCoord[24], ' WindowHandle', RCoord[24]+40, CCoord[24], 'yellow', 'false')
disp_message (WindowHandle1, 'angle= '+Angle, 'WindowHandle', RCoord[0], CCoord[0], 'red', 'false') 
dev_update_time ('on')
disp_continue_message (WindowHandle1, 'black', 'true')*移动到中心点
get_image_size(Image, Width1, Height1)
vector_angle_to_rigid(RCoord[24], CCoord[24], rad(Angle), Height1/2, Width1/2, 0, HomMat2D)
affine_trans_image(Image, ImageAffinTrans, HomMat2D, 'constant', 'false')write_image(ImageAffinTrans, 'bmp', 0, './图片/0')
stop ()

 

完整标定畸变矫正程序:

* This program measures the length of scratches in world
* coordinates in a perspectively distorted image*3.外参-畸变图像校正-cameracal -调正了第一个图作为外参pose
*set_origin_pose(PoseCalib,0,0,0.003,PoseNewOrigin)   因为首张图已经被调整 因此该处dx  dy  为0*************************************************************1.初始化******************************************************************************
* 关闭窗口
dev_close_window ()
* 更新程序计数器,更新变量,更新图形窗口
dev_update_off ()
* 设置区域填充模式
dev_set_draw ('margin')
* 读取图像
read_image (Image, '图片/1')
* 获取图像类型,宽度,高度,缓存数据
get_image_pointer1 (Image, Pointer, Type, Width, Height)
* 打开窗口
dev_open_window (0, 0, Width/2, Height/2, 'black', WindowHandle1)
* 设置字体信息
set_display_font (WindowHandle1, 14, 'mono', 'true', 'false')
* 显示图像
dev_display (Image)
* 右下角显示运行字样字符串
disp_continue_message (WindowHandle1, 'black', 'true')
stop ()* 1.内参标定 CamParam, PoseCalib
gen_self_Campar_and_PoseOrigin (WindowHandle1, Height, Width,\CamParam, PoseCalib, CalibDataID)
stop()*2.单像素对应距离   DistanceOnePixel
gen_self_DistanceOnePixel (PoseCalib, CamParam, PoseNewOrigin,\DistanceOnePixel)*3.求偏离值  把图像移动到正中间!
gen_self_FinalPose (WindowHandle1, CamParam, PoseNewOrigin, \Width, Height, DistanceOnePixel, PoseCalib, PoseNewOriginFinal)*4.map  消除径向畸变和视角畸变
read_image (ImagePespective, '图片/1')*内参 CamParam, 
* 外参 PoseNewOriginFinal, 
*图像的宽度和高度, 像素Width, Height, Width, Height,
*单像素对应距离DistanceOnePixel 8.11503e-05
* DistanceOnePixel:=0.000 08 29788   0.08mm  1
gen_image_to_world_plane_map(Map1, CamParam, PoseNewOriginFinal, Width, Height, \Width, Height,DistanceOnePixel, 'bilinear')DistanceOnePixel:=0.0000828126
write_object(Map1, 'Map1.obj')
*3.83674e-05*0.0000383674
read_object(Map1, 'Map1.obj')
*5.验证 和  测试 !
for Index := 1 to 1 by 1read_image(Image1, '图片/6')* 在这里对原始图像 Image1, 进行畸变矫正,ImageMapped1。* 不失真的图  map_image(Image1,Map1, ImageMapped1)*364  30mm   1像素  0.08mm *            2像素    1280  1024  2560 *2000=500万像素distance_pp(452  ,454 , 452 ,818, Distance)*误差  0.2mm误差*0.0302043
*     X:=Distance*DistanceOnePixel*验证精度是否足够dev_get_window(WindowHandle)
*     dev_open_window (0, 0, Width/2, Height/2, 'black', WindowHandle3)dev_display(ImageMapped1)column:=459dev_set_color('blue')dev_set_line_width(3)*调正  ----验证 畸变矫正的效果Genimage (ImageMapped1, Image, ImageAffinTrans, WindowHandle1)dev_clear_window()dev_display(ImageAffinTrans)gen_contour_polygon_xld (Polygon, [452,452], [column,column+0.030/DistanceOnePixel])dev_set_color('red')dev_set_line_width(1)gen_cross_contour_xld(Cross1, 451, column, 46, 0.785398)gen_cross_contour_xld(Cross2, 451, column+0.030/DistanceOnePixel, 46, 0.785398)disp_message (WindowHandle, '30cmm', 'window', 205, 195, 'red', 'false')dev_display (Polygon)dev_display (Cross1)dev_display (Cross2)disp_continue_message (WindowHandle, 'black', 'true')stop()
endfor

三大函数

* 1.内参标定 CamParam, PoseCalib

*   read_cam_par ('cam.dat', CamParam)* 标定文件名
CaltabName := 'caltab_30mm.descr'
* [Focus,Kappa,Sx,Sy,Cx,Cy,Width,Height]
StartCamPar := [0.008, 0, 4.8e-006, 4.8e-006, 640, 512, 1280, 1024]
*创建标定数据模型
create_calib_data ('calibration_object', 1, 1, CalibDataID)
*设置相机类型并初始化标定数据模型里的摄像机内部参数
set_calib_data_cam_param (CalibDataID, 0, 'area_scan_division', StartCamPar)
*为校正模型指定校正文件
set_calib_data_calib_object (CalibDataID, 0, CaltabName)
NumImages := 12list_image_files('./图片', 'default', [], ImageFiles)for i := 0 to NumImages by 1*读取图像read_image (Image, ImageFiles[i])*显示图像dev_display (Image)gen_rectangle1(Rectangle, 1, 1, 1024,1280)reduce_domain(Image, Rectangle, ImageReduced1)min_max_gray ( ImageReduced1, Image, 5, Min, Max, Range)scale_image (Image, ImageScaled, 255 / Range, -Min * 255 / Range)*获取校正板内边框以内的区域find_caltab (ImageScaled, Caltab, CaltabName, 3, 112, 5)*设置输出对象显示颜色dev_set_color ('green')*显示校正板内边框以内的区域dev_display (Caltab)*提取出图像中MARK点的位置并计算出摄像机外部参数find_marks_and_pose (Image, Caltab, CaltabName, StartCamPar, \128, 10, 18, 0.9, 15, 100, RCoord, CCoord, StartPose)*设置输出对象显示颜色dev_set_color ('red')*显示MARK点的位置disp_circle (WindowHandle1, RCoord, CCoord, gen_tuple_const(|RCoord|,2.5))dev_set_part (0, 0, Height-1, Width-1)*收集观察数据set_calib_data_observ_points (CalibDataID, 0, 0, i, RCoord, CCoord, 'all', StartPose)
*     stop()
endfor
dev_update_time ('on')
disp_continue_message (WindowHandle1, 'black', 'true')
stop ()
*开始校正摄像机 [-2.76405e-05, -7.47002e-06, 0.0684394, 10.0298, 5.70187, 358.571, 0]
calibrate_cameras (CalibDataID, Error)
*获取优化以后的摄像机内部参数
get_calib_data (CalibDataID, 'camera', 0, 'params', CamParam)
******保存相机内参,且该函数只能保存内参***
write_cam_par(CamParam,'cam.dat')
****************************
*获取优化以后的校正对象姿势,相对于当前参考相机。
get_calib_data (CalibDataID, 'calib_obj_pose', [0,0], 'pose', PoseCalib)
write_pose(PoseCalib, 'poseOrigin.dat')
return ()

*2.单像素对应距离   DistanceOnePixel

*矫正后再测量
*选取两个像素点  2个点求距离
Image_X1:=100
Image_Y1:=100Distance_XY:=500
Image_X2:=Image_X1+Distance_XY
Image_Y2:=Image_Y1+Distance_XYgen_cross_contour_xld(Cross1, Image_X1, Image_Y1, 46, 0.785398)
gen_cross_contour_xld(Cross2, Image_X2, Image_Y2, 76, 0.785398)
*考虑标定板厚度的影响  PoseNewOrigin在这里
*[0.0209422, -0.0257558, 0.56891, 7.69086, 10.9034, 359.249, 0]* 0  旋转轴种类
* pose1:=[0,0,0.003,0,0,0,0]
* pose_compose(PoseCalib,pose1,PoseCompose1)* 0.003  标定板的厚度  3mm  0.003m  
set_origin_pose(PoseCalib,0,0,0,PoseNewOrigin)
*将像素坐标转化为世界坐标(单位m)
image_points_to_world_plane(CamParam, PoseNewOrigin, Image_Y1, Image_X1, 'm', World_X1, World_Y1)
image_points_to_world_plane(CamParam ,PoseNewOrigin, Image_Y2, Image_X2, 'm', World_X2, World_Y2)*******************************************************************************************
*计算世界坐标距离
distance_pp(World_Y1, World_X1, World_Y2, World_X2, DistanceWorld)
*计算像素坐标
distance_pp(Image_X1,Image_Y1,Image_X2,Image_Y2,DistanceImage)*每个像素对应的世界坐标距离
DistanceOnePixel:=DistanceWorld/DistanceImage
return ()

*3.求偏离值  把图像移动到正中间!

WindowHandle1Out := WindowHandle1disp_3d_coord_system (WindowHandle1Out, CamParam, PoseNewOrigin, 0.05)*调整世界坐标到中心偏移量
OffSetX:=(Width/2)*DistanceOnePixel
OffSetY:=(Height/2)*DistanceOnePixel*
*************************************************************3.图像转换****************************************************************************
*这张图  是 世界坐标系的参考姿态图   ,与外参demo  中游标卡尺的坐标系是类似的作用*调整相机外参
*假如需要重新拍一张图 ,这个图 与世界坐标系 的姿态一致。由于是平面,不考虑  x  y  的变化,只考虑z方向角度的变化。
*所以这里是第5个值 需要替换 ,RZ
*PoseCalibRot 是机器人的坐标系set_origin_pose (PoseNewOrigin, -OffSetX, -OffSetY, 0, PoseNewOriginFinal)return ()

相关文章:

  • 57认知干货:AI机器人产业
  • AIDC智算中心建设:计算力核心技术解析
  • 【深入浅出MySQL】之数据类型介绍
  • ES6入门---第三单元 模块一:类、继承
  • 分享一个Android中文汉字手写输入法并带有形近字联想功能
  • DeepSeek Copilot idea插件推荐
  • Allegro23.1新功能之如何设置高压爬电间距规则操作指导
  • Mamba+Attention+CNN 预测模型:破局长程依赖的计算机视觉新范式
  • ActiveMQ 与其他 MQ 的对比分析:Kafka/RocketMQ 的选型参考(二)
  • 【JLINK调试器】适配【大华HC32F4A0芯片】的完整解决方案
  • 数据结构--树状数组
  • opencv的contours
  • ABC404G 题解
  • 数据结构(4) 堆
  • Terraform 中的 external 数据块是什么?如何使用?
  • 软考-软件设计师中级备考 12、软件工程
  • Java 中使用 Callable 创建线程的方法
  • 【办公类-99-04】20250504闵豆统计表excle转PDF,合并PDF、添加中文字体页眉+边框下划线
  • postgresql数据库基本操作
  • JVM happens-before 原则有哪些?
  • 中南财经政法大学法学院党委副书记易育去世,终年45岁
  • 电商平台集体出手,多措并举助力外贸企业拓内销
  • 戴上XR头盔,五一假期在上海也能体验“登陆月球”
  • 美国第一季度经济环比萎缩0.3%,特朗普:怪拜登,与关税无关
  • 近七成科创板公司2024年营收增长,285家营收创历史新高
  • 国台办:民进党当局所谓“对等尊严”,就是企图改变两岸同属一中