Halcon例程(基于多个标定图的单目相机标定)详解—— Camera_calibration_multi_image.hdev

一、前言

在我的工业相机专栏里已经将相机标定涉及到的理论部分讲解完毕,为什么要标定以及标定要求出什么参数呢,用一个Halcon 例程来帮助理解。
这个例程是比较经典的标定程序,基本将标定过程讲的比较清楚,用的标定图像是系统自带的,如果想自己做可以在Halcon助手选项里拍照生成。

二、代码

* 设置窗口和字体
ImgPath := '3d_machine_vision/calib/'
dev_close_window ()
dev_open_window (0, 0, 640, 480, 'black', WindowHandle)
dev_update_off ()
dev_set_draw ('margin')
dev_set_line_width (3)
set_display_font (WindowHandle, 22, 'mono', 'true', 'false')
* 
* 相机标定过程
* 
* 生成面阵相机初始参数,参数均为相机已知参数
* (: : 焦距, 畸变因子, Sx, Sy, Cx, Cy, 图像宽度, 图像高度 : CameraParam存储元组)
* (Sx, Sy为传感器芯片上两个相邻单元之间的水平竖直距离,也就是像素的大小,单位为m/像素;Cx, Cy为图像原点的行列坐标,单位为像素;)
gen_cam_par_area_scan_division (0.012, 0, 0.00000375, 0.00000375, 640, 480, 1280, 960, StartCamPar)
*创建Halcon标定数据模型(标定类型,相机数量,标定物数量,模型句柄)
*其作用在于指定相机标定类型,设置标定过程,存储标定数据和结果。
create_calib_data ('calibration_object', 1, 1, CalibDataID)
*设定相机初始参数(句柄,相机参数索引,相机类型,起始相机参数)
*此段程序跑完的句柄见下图。
set_calib_data_cam_param (CalibDataID, 0, [], StartCamPar)
*设定标定板初始参数(句柄,标定板数量索引,标定板描述(文件名或者标定板所有点的三维坐标))此例生成三维坐标系坐标值(x,y,z),其中z为0;坐标原点在finder模式的中心Mark点中心,坐标系的z轴指向标定板,x轴指向右侧,y轴指向下方,视角沿z轴。
set_calib_data_calib_object (CalibDataID, 0, 'calplate_80mm.cpd')//此文件可用记事本打开,里面记录了标定板五个mark模式的点坐标和半径。
calibration marks at y = -0.0290538 m
-0.0374193548387097 -0.0290537554818005 0.000645161290322581

在这里插入图片描述

*读图,并生成落轮廓和点的特征参数值
NumImages := 7
for I := 1 to NumImages by 1
*读图,路径在C盘用户公共文档里,% 2d是将数字按宽度为2,采用右对齐方式输出,若数据位数不到2位,则左边补空格,所以文件名为calib_0X。read_image (Image, ImgPath + 'calib_image_' + I$'02d')dev_display (Image)*寻找标定板并在模型中设定提取的点和轮廓信息*(图像变量,句柄,相机的索引,标定板的索引,计数变量,参数名(使用六边形标定板,设置额外的参数值,可以使图像平滑等),参数值)*该算子将标定板每个点的轮廓和点坐标,索引和此图像标定板相对于相机坐标系的位姿提取出来,保存在句柄中。*find_caltab在图像中寻找标定板是基于标定板的特征——在一个亮的区域中存在黑色Mark点*算子对图像高斯滤波(核大小为SizeGauss),接着阈值分割(与之大小为MarkThresh)将标定板的区域找出来.find_calib_object (Image, CalibDataID, 0, 0, I, [], [])*从标定数据模型中获取基于轮廓的观测数据*(轮廓变量,句柄,返回标定板查找模式的轮廓内含三个参数(marks(返回每一个轮廓,calib(返回查找模式的轮廓),last_caltab(会返回上次成功的查找结果,但会忽略索引信息)),相机索引,标定板索引,变量)* 标定板查找器:有两种模式,一种是特殊标记六边形(即一个标记及其六个相邻标记),其中四个或六个标记包含一个孔;另外是带有矩形排列标记的校准板:校准板的边缘在一角有一个三角形。这里是第一种,结果如下图所示。get_calib_data_observ_contours (Caltab, CalibDataID, 'caltab', 0, 0, I)*从标定数据模型中获取基于点的观测数据get_calib_data_observ_points (CalibDataID, 0, 0, I, Row, Column, Index, StartPose)dev_set_color ('green')dev_display (Caltab)dev_set_color ('red')*画出坐标的轮廓,轮廓以中心点的方式显示(窗口句柄,中心点行坐标,列坐标,半径)tuple_gen_const(: : Length, Const : Newtuple)(元组长度,常量初始值)disp_circle (WindowHandle, Row, Column, gen_tuple_const(|Row|,1.5))
endfor

在这里插入图片描述
关于find_calib的更多细节见链接:
Halcon相机标定

*最重要的算子:相机标定,通过同步的最小化过程确定所有相机参数;
*计算相机内外参矩阵,原理见链接(https://blog.csdn.net/baidu_35536188/article/details/109772056)
*(句柄,优化后的反投影的均方根误差(RMSE),单位为像素,该误差用来反映优化是否成功,越接近0表示效果越好)
calibrate_cameras (CalibDataID, Errors)
*获取相机标定数据--内参值,将其存在CamParam上。
get_calib_data (CalibDataID, 'camera', 0, 'params', CamParam)
*获取标定板数据,将其第一幅图的位姿存在Pose里。
get_calib_data (CalibDataID, 'calib_obj_pose', [0,1], 'pose', Pose)* 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.
* *设置新的坐标原点。在Z轴坐标加0.02,主要是考虑标定板的厚度,该算子通过DX、DY和DZ给定的向量转换3D poseIn的原点,并以poseNewOrigin形式返回结果。
set_origin_pose (Pose, 0, 0, 0.002, Pose)
* measure the distance between the pitch lines

在这里插入图片描述
在这里插入图片描述

read_image (Image, ImgPath + 'ruler')
dev_display (Image)
* 准备提取垂直于矩形长轴的直边。 矩形的中心在(Row,Column),Phi为矩形主轴的角度,Lenth1和Lenth2为两轴的长度,即矩形两边长度的一半。
* (矩形中心点的行坐标,列坐标,矩形的纵轴与水平的角度(弧度),矩形的半宽,矩形的半高,图像的宽,高,要使用的插值类型,测量对象句柄)
gen_measure_rectangle2 (690, 680, rad(-0.25), 480, 8, 1280, 960, 'bilinear', MeasureHandle)
*提取垂直于矩形或环形弧的边缘对
*(图像,句柄,高斯平滑的西格玛参数值,最小边缘幅度,灰度值转换的类型以确定边缘如何成对,边缘对第一条边的中心的Row坐标,列坐标,
边缘对第一条边的边缘幅度(带符号),边缘对第二条边的中心的Row坐标,列坐标,边缘幅度,边缘对内部之间的距离,边缘间距离)
measure_pairs (Image, MeasureHandle, 0.5, 5, 'all', 'all', RowEdgeFirst, ColumnEdgeFirst, AmplitudeFirst, RowEdgeSecond, ColumnEdgeSecond, AmplitudeSecond, IntraDistance, InterDistance)
Row := (RowEdgeFirst + RowEdgeSecond) / 2.0
Col := (ColumnEdgeFirst + ColumnEdgeSecond) / 2.0
*显示X点,如下图所示。
disp_cross (WindowHandle, Row, Col, 20, rad(45))
*将图像点转换为世界坐标系的z=0平面
*(相机内参,位姿,行,列,单位,世界坐标系的X坐标点,Y坐标点)
image_points_to_world_plane (CamParam, Pose, Row, Col, 'mm', X1, Y1)
*计算两点间的距离
distance_pp (X1[0:11], Y1[0:11], X1[1:12], Y1[1:12], Distance)
*求平均距离和
tuple_mean (Distance, MeanDistance)
*计算距离的标准差
tuple_deviation (Distance, DeviationDistance)
disp_message (WindowHandle, 'Mean distance: ' + MeanDistance$'.3f' + 'mm +/- ' + DeviationDistance$'.3f' + 'mm', 'window', 30, 60, 'yellow', 'false')

在这里插入图片描述

三、总结

Halcon 的标定步骤总结如下:

  1. gen_cam_par_area_scan_division:生成相机参数矩阵;
  2. create_calib_data,set_calib_data_cam_param, set_calib_data_calib_object:创建标定数据模型,并设定相机和标定板的参数值,包括相机起始内参和标定板的坐标系。
  3. find_calib_object,在多幅标定图像中寻找标定板,并提取其轮廓和点特征,生成相对于相机坐标系的位姿矩阵(7维)。
  4. calibrate_cameras,计算内外参,并计算误差值。
  5. 读实际要测量的图,设定感兴趣矩形区域,并通过边缘检测计算边缘点坐标并标记出来,并根据计算出的内外参将二维坐标转为3维坐标,计算出偏差。
    综合下来,感觉HALCON标定的过程还是比较清晰的,关键算子里面的程序还是需要理解一下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/256357.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SkipList 跳表

为什么选择跳表 目前经常使用的平衡数据结构有:B树,红黑树,AVL树,Splay Tree, Treep等。 想象一下,给你一张草稿纸,一只笔,一个编辑器,你能立即实现一颗红黑树,或者AVL树…

机器学习——深度学习之卷积神经网络(CNN)——LeNet卷积神经网络结构

目录 一、卷积神经网络 1、卷积神经的作用 2、LeNet 1)数据库准备——minst 2)模型 二、关于卷积神经网络结构的一些术语定义 1、特征图(Feature map) 2、height(长度)、width(宽度&…

工业相机(3D)主要参数详述

一、前言 准确的完成相机选型是一个视觉工程师必备的技能,而选型前必须对其内部参数了如指掌。工业相机是一种比较复杂的产品,其参数很多,每个参数可能会有不同的标准,下面对主要的参数会做比较详细的阐述。 二、参数详述 2.1 …

JAVA8永久代

在Java虚拟机(以下简称JVM)中,类包含其对应的元数据,比如类的层级信息,方法数据和方法信息(如字节码,栈和变量大小),运行时常量池,已确定的符号引用和虚方法表…

Struts 2初体验

Struts2简介: Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。 Struts 2 目录结构:     apps目录:Struts2示例…

机器学习——深度学习之数据库和自编码器

目录 一、数据库——数据获取 1、Mnist 2、ImageNet 二、自编码器(Auto-encoder)——参数初始化 1、功能 2、基本思想 1)训练第一层 2)训练第二层及以后的神经网络 ​ 3)利用BP对整个神经网络的参数初始值进…

Halcon例程详解 (深度图转换为3D图像)—— xyz_attrib_to_object_model_3d

一、前言 深度图向点云图进行转换是进行3D检测项目时会遇到的问题,halcon里也有针对此问题的相关例程,下面对此例程进行分析。通过学习此例程,我们可以掌握如何将一张深度图像和一张正常二维图像转换为3D点云。 二、分析 * 初始化界面 dev…

动态代理之Cglib浅析

什么是Cglib Cglib是一个强大的,高性能,高质量的代码生成类库。它可以在运行期扩展JAVA类与实现JAVA接口。其底层实现是通过ASM字节码处理框架来转换字节码并生成新的类。大部分功能实际上是ASM所提供的,Cglib只是封装了ASM,简化了…

机器学习——深度学习之卷积神经网络(CNN)——AlexNet卷积神经网络结构

目录 一、AlexNet卷积神经网络结构模型 1、数据库ImageNet 2、AlexNet第一层卷积层 二、AlexNet卷积神经网络的改进 1、非线性变化函数的改变——ReLU 2、最大池化(Max Pooling)概念的提出——卷积神经网络通用 1)池化层 2&#xff0…

C#委托——基础2

在上一篇随笔中,简要说明了怎样定义委托,定义事件,订阅事件,最后也实现了效果,就是当员工类的某个对象,执行某个事件时,委托事件被触发,后面也得到了结果,但是想象一下实…

机器学习——深度学习之编程工具、流行网络结构、卷积神经网络结构的应用

目录 一、编程工具 caffe实现LENET-5 二、流行的网络结构 1、VGGNET 2、Googlenet ​ 3、ResNet​ ​ 三、卷积神经网络的应用 1、人脸识别 ​ 2、人脸验证 3、人脸特征点检测 4、卷积神经网络压缩 一、编程工具 caffe的优点:模型标准化,源代码…

Halcon例程详解(激光三角系统标定)—— calibrate_sheet_of_light_calplate.hdev

前言 1 激光三角测距 激光三角测距法原理很简单,是通过一束激光以一定的入射角度照射被测目标,激光在目标表面会产生漫反射,在另一角度利用透镜对反射激光汇聚成像,光斑成像在CCD(Charge-coupled Device,感光耦合组件)位置传感器上。当被测物体沿激光方向发生移动时,…

【tenserflow】——数据类型以及常用属性

目录 一、什么是Tensor? 二、Tensorflow常见数据类型 三、Tensorflow常见属性device\cpu\gpu\ndim\shape\rank等 1、创建一个tensor 1)tf.constant() 2)tf.Variable() 2、判断一个变量是否为tensor张量 3、生成不同设备(cpu,gpu&#x…

网页开发浏览器兼容性问题

1、在ie6下的双margin问题 在ie6下,设置了float的元素,以float:left为例,如图所示。会出现第一个浮动元素,即相对于父级元素浮动的,会出现双倍margin的问题。 注意仅仅是相对于父级元素浮动的,即第一个会出…

【tensorflow】——创建tensor的方法

目录 1、tf.constant() 2、tf.Variable() 3、tf.zeros():用0去填充指定形状的数组 4、tf.convert_to_tensor(a,dtypetf.int32) 5、tf.ones():用1去填充指定形状的数组 6、tf.fill():用指定的元素去填充指定形状的数组 7、随机化初始化进行创建 1)normal正态分…

Halcon —— 图像像素类型与转换

图像类型 就目前工业领域主流的图像处理工具halcon来讲,有以下几种图像类型:‘byte’, ‘complex’, ‘cyclic’, ‘direction’, ‘int1’, ‘int2’, ‘int4’, ‘int8’, ‘real’, ‘uint2’,具体含义如下图所示。 ‘byte’ 每像素1字节…

Halcon例程详解(基于卡尺工具的匹配测量方法) —— measure_stamping_part.hdev

前言 1卡尺工具介绍 Halcon中的Metrology方法即为卡尺工具,可用来拟合线,圆,这种方法对于目标比背景很明显的图像尺寸测量是很方便的,不需要用blob进行边缘提取等,但缺点也很明显,需要目标的相对位置基本…

【TensorFlow】——不同shape的tensor在神经网络中的应用(scalar,vector,matrix)

目录 ​ 1、scalar——标量 1)在神经网络中存在的场景 2)one_hot编码 3)举例应用 2、vector——向量 ​ 3、matrixs——矩阵 4、dim3的tensor 5、dim4的tensor 6、dim5的tensor 本文主要的目的是让初学者对tensor的各种形式的使用场…

Java - I/O

File类 java.io操作文件和目录,与平台无关。具体的常用实例方法: File file new File("."); // 以当前路径创建名为 "." 的 File 对象   文件目录信息函数     -   String getName/Path/Parent(): 文件名/路径…

Halcon —— 边缘检测算子详解

一、算子介绍 1.1 种类 halcon内常用的边缘检测算子包括如下几种: 1.edges_image: 提取2D 图像边缘 2.edges_sub_pix:提取2D图像亚像素边缘 3.edges_object_model_3d :提取3D图像边缘 4.edges_color和edges_color_sub_pix:提取彩…