Halcon例程(基于3D形状匹配识别方法)详解 —— create_shape_model_3d_lowest_model_level.hdev

一、例程简介

最近在研究3D识别方面的东西,查了不少资料,发现halcon里有不少关于三维物体识别的例程,这里对其中一个做出详解。该例程是基于三维匹配方法的,因为有三维模型SM3,所以不需要自己创建;另因为例程中的图像有多种不同的姿态,建立三维模型所需要的内存会很大,所以设定最低模型级别,显著降低了算法运行时间,但相对的,会损失算法的鲁棒性和检索时间。
在这里插入图片描述

二、例程详解

dev_update_off ()
* 设置面扫相机参数,参数可通过相机校正来获取。此算子为库函数,通过Division畸变模型生成一个相机参数元组。
* 其中参数含义为(焦距,模拟径向透镜畸变的畸变系数,传感器上两个相邻单元之间的水平距离,传感器上两个相邻单元之间的垂直距离,光心列坐标,光心行坐标,图宽,图高,输出相机参数)
gen_cam_par_area_scan_division (0.0269462, -354.842, 1.27964e-005, 1.28e-005, 254.24, 201.977, 512, 384, CamParam)
{ CameraParam :=['area_scan_division',Focus,Kappa,Sx,Sy,Cx,Cy,ImageWidth,ImageHeight]
return () }
* 获取相机参数,返回要求的图像宽参数。
get_cam_par_data (CamParam, 'image_width', IWidth)
{
*返回相机的类型和参数名
get_cam_par_names (CameraParam, CameraType, CameraParamNames)
* 
* 找到相机数据的索引并返回对应的值。
ParamValue := []
*依次读取参数名,ParamName在get_cam_par_names已被赋值,为'image_width'
for Index := 0 to |ParamName| - 1 by 1ParamNameInd := ParamName[Index]if (ParamNameInd == 'camera_type')ParamValue := [ParamValue,CameraType]continueendif* I为'image_width'在CameraParamNames的索引值,为7I := find(CameraParamNames,ParamNameInd)if (I != -1)*将图宽值赋值给ParamValueParamValue := [ParamValue,CameraParam[I]]elsethrow ('Unknown camera parameter ' + ParamNameInd)endif
endfor
return () }
get_cam_par_data (CamParam, 'image_height', IHeight)
* 
read_image (Image, 'tile_spacers/tile_spacers_color_01')
dev_close_window ()
dev_open_window (0, 0, 512 * 1.5, 384 * 1.5, 'white', WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_set_line_width (3)
dev_clear_window ()
disp_message (WindowHandle, 'Reading the 3D shape model file from disk ...', 'window', 12, 12, 'black', 'false')
* 如果磁盘没有可用的话就创建3D模型
try
*  读取3D形状模型,具体地址在C盘MVTec文件夹下examples\hdevelop\3D-Matching\Shape-Based。read_shape_model_3d ('tile_spacer.sm3', ShapeModel3DID)
catch (Exception)* 读目标3D模型的DXF文件,CAD格式,但因为上一步可以运行,所以这一部分没用了。* 参数(文件名,文件单位的转换尺度(单位为100um),参数名,参数值,3D模型句柄,状态信息)read_object_model_3d ('tile_spacer.dxf', 0.0001, [], [], ObjectModel3DID, DXFStatus)*为指定操作准备3D模型,可以计算所需要的值并储存在objectModel3D*参数(3D模型句柄,目的,指定是否应覆盖已存在的数据,参数名,参数值)prepare_object_model_3d (ObjectModel3DID, 'shape_based_matching_3d', 'true', [], [])disp_message (WindowHandle, 'Reading the 3D shape model file from disk ... not found!', 'window', 12, 12, 'red', 'false')disp_message (WindowHandle, 'Creating the 3D shape model (may take a few seconds) ...', 'window', 42, 12, 'black', 'false')count_seconds (S1)* 创建3D形状模型,是通过计算三维物体模型在用户指定的姿势范围内的不同视图而生成的。通过在三维物体模型周围放置虚拟摄像机,并将三维物体模型投影到每个虚拟摄像机位置的图像平面上,自动生成视图;* 因此,在生成三维形状模型时,不使用对象的图像,只使用在objectModel3D中传递的三维对象模型,所有视图的形状表示都存储在三维形状模型中,该模型返回到shapeModel3DID中。在创建三维形状模型之前,必须校准相机,以防止畸变。* 参数(3D模型句柄,相机参数,沿x轴/x分量旋转的罗德里格斯矢量,y轴,z轴,参考向量的旋转值,模型视图的最小经度,* 最大经度,模型视图的最小纬度,最大纬度,模型视图的最小摄影机滚动角度,最大角度,模型视图的最小摄影机对象距离,最大距离,搜索图像中对象的最小对比度,用于控制运算符行为的(可选)参数的名称(最低模型级别),可选参数值,句柄)create_shape_model_3d (ObjectModel3DID, CamParam, 0, 0, 0, 'gba', -rad(60), rad(60), -rad(60), rad(60), 0, rad(360), 0.26, 0.27, 10, 'lowest_model_level', 3, ShapeModel3DID)count_seconds (S2)T := S2 - S1disp_message (WindowHandle, 'Creation time: ' + T$'.3' + ' s', 'window', 72, 12, 'black', 'false')trydisp_message (WindowHandle, 'Writing model to disk ...', 'window', 102, 12, 'black', 'false')*存储3D模型write_shape_model_3d (ShapeModel3DID, 'tile_spacer.sm3')catch (Exception)disp_message (WindowHandle, 'Writing model to disk ... failed!', 'window', 102, 12, 'red', 'false')disp_continue_message (WindowHandle, 'black', 'true')stop ()endtry
endtry
*显示模型信息
disp_lowest_model_level_info (WindowHandle)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 匹配
Times := []
NumImages := 12
for I := 1 to NumImages by 1read_image (Image, 'tile_spacers/tile_spacers_color_' + I$'02')dev_display (Image)* * 查找三个三维模型的实例,将“border”模型设置为“true”,因为对象可能会接触图像边界* 程序开始到现在过去的时间count_seconds (Seconds1)*在图像中找出一个3D模型的最佳匹配*参数(输入图像,3D模型的句柄,最低分数(值越大,搜索速度越快),贪婪度(值越大,搜索越快,但更容易失败),(该值决定搜索过程中金字塔层的数量,设为0,则数量为创建模型时的指定值),控制操作行为的参数名,参数值,模型的3D位姿,姿态参数的36个协方差或6个标准差,分数)find_shape_model_3d (Image,  ShapeModel3DID,0.7, 0.85, 0, ['num_matches','max_overlap','border_model'], [3,0.75,'true'], Pose, CovPose, Score)count_seconds (Seconds2)计算匹配时间Time := Seconds2 - Seconds1Times := [Times,Time]*通过使用匹配的姿势将三维形状模型投影到图像中,将找到的匹配项可视化for J := 0 to |Score| - 1 by 1*显示轮廓PoseTmp := Pose[J * 7:J * 7 + 6]*将三维形状模型的边投影到图像坐标中。project_shape_model_3d (ModelContours, ShapeModel3DID, CamParam, PoseTmp, 'true', rad(30))dev_set_color ('yellow')dev_display (ModelContours)* 显示3D模型的坐标系dev_set_colored (3)disp_3d_coord_system (WindowHandle, CamParam, PoseTmp, 0.015)endforfor K := 0 to |Score| - 1 by 1* 显示找到的位姿的参数PoseTmp := Pose[K * 7:K * 7 + 6]*自定义函数,显示位姿信息display_match_pose (ShapeModel3DID, PoseTmp, WindowHandle){*查找模型参数(参考点坐标),get_shape_model_3d_params (ShapeModel3DID, 'reference_point', ReferencePoint)*查找相机参数get_shape_model_3d_params (ShapeModel3DID, 'cam_param', CamParam)
* 
* Project the reference point
* 将三维姿态转换为齐次变换矩阵。
pose_to_hom_mat3d (Pose, HomMat3D)
*对点应用任意仿射3D变换
affine_trans_point_3d (HomMat3D, ReferencePoint[0], ReferencePoint[1], ReferencePoint[2], X, Y, Z)
*将3D点投影到(亚)像素图像坐标中。
project_3d_point (X, Y, Z, CamParam, Row, Column)
* 显示参考点坐标
Message := 'Pose:'
Message[1] := '   X: ' + (1000 * Pose[0])$'4.1f' + ' mm'
Message[2] := '   Y: ' + (1000 * Pose[1])$'4.1f' + ' mm'
Message[3] := '   Z: ' + (1000 * Pose[2])$'4.1f' + ' mm'
Message[4] := '   Alpha: ' + Pose[3]$'4.1f' + '°'
Message[5] := '   Beta: ' + Pose[4]$'4.1f' + '°'
Message[6] := '   Gamma: ' + Pose[5]$'4.1f' + '°'
disp_message (WindowHandle, Message, 'image', Row, Column - 30, 'black', ['#ffffffcc','false'])
return () }endfor*在左上角显示匹配用时disp_message (WindowHandle, |Score| + ' Match(es) found in ' + Time$'4.2f' + ' s', 'window', 12, 12, 'dark green', ['white','false'])if (I < NumImages)disp_continue_message (WindowHandle, 'black', ['white','false'])stop ()endif
endfor
* 
disp_end_of_program_message (WindowHandle, 'black', ['white','false'])

三、总结

下面对上述基于形状的3D匹配方法进行总结,主要包含以下几个步骤:
1.读取/创建3D模型read_object_model_3d/create_shape_model_3d;
2.对二维图像进行3D匹配,计算得分,find_shape_model_3d
3将匹配结果可视化,project_shape_model_3d,project_3d_point
总的来看,这种3D匹配方法还是比较好用的,对于物体间遮挡的情况也可以进行识别,难点在于调参吧。该方法的原理根据三维模型的位姿信息来对图像中的目标进行搜索并判断,返回一个匹配度值,网上没有更为详细的代码,应该是比较难吧,基于点云的还有不少资料,目前业界关于3D识别方面的项目还没有很普遍,研究者较少,希望后面有所改善。
如果大家有意见和想法,可以一起交流,注意点赞评论哦。

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

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

相关文章

15.瀑布流、测量

排行界面TopProtocol &#xff1a;json数据就是写字符串&#xff0c;所以不需要写bean对象public class TopProtocol extends BaseProtocol<List<String>> { Override public List<String> paserJson(String json) { List<String> datasnew ArrayList&…

linear-gradient线性渐变

background:linear-gradient(180deg, sliver 20%, skyblue 80%, gray 100%);180deg 是线性渐变的角度,水平方向;如果是90deg,则是垂直方向. silver 20% 是最上面的颜色和该颜色所在的位置,可以为负值,,如 linear-gradient(180deg, silver -7%, pink 80%, skyblue 127%);的效果是…

C# —— 简单工厂设计模式详述

一、基本概念 众所周知&#xff0c;C#是一种面向对象的语言&#xff0c;而其中封装&#xff0c;继承&#xff0c;多态是面向对象的三大重要特征&#xff0c;简单工厂的设计模式则可以完全体现这些特征。要彻底理解这个模式&#xff0c;必须要先将封装&#xff08;访问修饰符的…

工业相机常用类型详述

一、工业相机定义 工业相机是应用于工业领域、安防和交通等对相机要求较高领域的摄像机&#xff0c;功能就是将光信号转变成有序的电信号&#xff0c;此信号经过模数转换为数字信号&#xff0c;然后传递给图像处理器。与一般的家用相机相比&#xff0c;其具有更高的稳定性能&a…

机器学习——SVM之python实现数据样本标准化和归一化

目录 一、标准化和归一化的目的 1、标准化 2、归一化 二、标准化和归一化常用的理论公式 1、归一化 2、标准化 三、python实现SVM样本数据标准化和归一化 1、标准化 2、归一化 本文源代码&#xff1a;《机器学习——支持向量机SVM之python实现简单实例一》 一、标准化…

[黑群晖经典教程] 一步一步建立自己的黑群晖

【申明&#xff1a;本文并非本人所作&#xff0c;为内部网络中一位大神所写&#xff0c;个人觉得写得很好&#xff0c;遂原文搬了过来&#xff0c;如有侵犯原作者的权利&#xff0c;请及时与我联系】 PS:有好几个兄弟觉得我擅自转发&#xff0c;不是很妥。解释一下&#xff1a;…

C++和Opencv4.5 实现全景图像拼接

前言 最近刚下了最新版的opencv4.5&#xff0c;急不可待的试下操作&#xff0c;就用了opencv自带的Stitcher类拼接下图像&#xff0c;结果傻眼了&#xff0c;程序显示Stitcher没有createDefault成员&#xff0c;看了好久&#xff0c;终于找到了解决方法。 Stitcher原理 Stit…

机器学习——python实现SVM模型w,b的查看

基于源代码&#xff1a;《机器学习——支持向量机SVM之python实现简单实例一》进行讲解 1、线性模型 这里以二特征三类&#xff0c;一对多策略为案例 kernel “linear”&#xff1a;线性核&#xff0c;参数有w&#xff0c;b 线性模型的决策边界是&#xff1a;w0iTx0i w1i…

移动端输入框弹出键盘控制

在移动端&#xff0c;我们公司通过输入框主要收集用户的姓名和电话&#xff0c;以下是对输入框获取焦点时&#xff0c;控制弹出键盘的样式来增强用户体验。 输入姓名 我们的用户都是中国人&#xff0c;输入用户名为中文&#xff0c;所以弹出键盘是输入中文状态即可&#xff0c;…

相机标定(一) —— 深入理解齐次坐标及其作用

一、什么是齐次坐标和齐次坐标系 齐次坐标 齐次坐标是一个相机标定问题的关键理论之一&#xff0c;所以就此问题分析一下。 单从定义上来讲&#xff0c;齐次坐标&#xff08;投影坐标&#xff09;就是用N1维来代表N维坐标&#xff08;点和向量&#xff09;&#xff0c;也可说…

机器学习——图解SVM中gamma和c参数的作用

参数c和gamma的作用 我们通过下图详解参数c的作用&#xff0c;首先我们以一个简单的线性分类器为例&#xff0c;上一个博客中我们知道影响分类器的主要因素是支持向量&#xff0c;即虚线上的样本&#xff0c;如下图可知&#xff1a; 但当正负样本的分布在如下情况时&#xff0…

面试题(十四)

唐巧前辈说这些都是 iOS 的基础问题&#xff0c;应该对此深入的了解。当初看到时&#xff0c;大部分回答不上来&#xff0c;因为平时没有好好思考整理过。这里大部分的概念大多会在学习 OC 的过程中遇到过&#xff0c;但还是得经过写代码才能有更深的理解。反正我当初看那些设计…

工业相机基础知识详述 —— 焦平面,像平面,弥散圆,光圈,分辨率,景深,接口,靶面尺寸

一、焦平面 想到焦平面&#xff0c;很多人不由自主就想到不就是焦点所在的垂直于光轴的平面吗&#xff1f;其实其背后隐藏这更多的东西。 1&#xff09;焦点不止一个 对于一般拍摄场景来说&#xff0c;光通过一个凸透镜&#xff0c;汇聚不到一个点&#xff0c;越靠近中轴线的…

相机标定(二)深入理解四大坐标系与其变换关系

一、前言 视觉系统一共有四个坐标系&#xff1a;像素平面坐标系&#xff08;u,v&#xff09;、图像坐标系&#xff08;x,y&#xff09;、相机坐标系&#xff08;Xc,Yc,Zc&#xff09;和世界坐标系&#xff08;Xw,Yw,Zw&#xff09;&#xff0c;如下图所示。每种坐标系之间均存…

相机标定(三) —— 畸变校正

一、前言 根据针孔模型&#xff0c;物体和成像之间参数会满足相似三角形的关系。但现实中会存在装配误差和透视失真等原因&#xff0c;导致这种关系无法成立&#xff0c;使理想成像与实际成像存在误差&#xff0c;这种误差即称为畸变。 畸变分为径向畸变&#xff0c;切向畸变和…

SVG技术入门:线条动画实现原理

相信大家都见到过这样神奇的技术&#xff1a;一副线条构成的画能自动画出自己。非常的酷。Jake Archibald是这种SVG技术的首创者&#xff0c;并且写了一篇非常好的文章来描述它是如何实现的。Brian Suda也在24 Ways网站上讨论过它。 Polygon使用它在一篇设计方面的文章里创造出…

机器学习——人工神经网络之BP算法编程(python二分类数据集:马疝病数据集)

目录 一、理论知识回顾 1、神经网络模型 2、明确任务以及参数 1&#xff09;待估参数&#xff1a; 2&#xff09;超参数&#xff1a; 3&#xff09;任务 3、神经网络数学模型定义 1&#xff09;激活函数 ​ 2&#xff09;各层权重、阈值定义 3&#xff09;各层输入输…

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

一、前言 在我的工业相机专栏里已经将相机标定涉及到的理论部分讲解完毕&#xff0c;为什么要标定以及标定要求出什么参数呢&#xff0c;用一个Halcon 例程来帮助理解。 这个例程是比较经典的标定程序&#xff0c;基本将标定过程讲的比较清楚&#xff0c;用的标定图像是系统自…

SkipList 跳表

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

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

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