十一期间在家用期间研读了下Halcon的variation_model模型,基本上全系复现了他的所有技术要求和细节,这里做个记录。

  其实这个模型的所有原理都不是很复杂的,而且Halcon中的帮助文档也讲的很是清楚,所以通过猜测、测试、编码基本能搞清楚是怎么回事。

  关于这个模型,Halcon里有如下十来个函数:

  create_variation_model、prepare_variation_model, train_variation_model、compare_variation_model、prepare_direct_variation_model、clear_variation_model, clear_train_data_variation_model, compare_ext_variation_model, get_thresh_images_variation_model, get_variation_model、 clear_train_data_variation_model, write_variation_model 。

  看起来涉及到了蛮多的东西的。

  那么一般的工作流程是:create_variation_model  ---> train_variation_model ---> prepare_variation_model  --->   compare_variation_model  ---> clear_variation_mode。

  即: 创建模型,然后训练模型,接着就是准备模型,这个时候就可以使用了,那么可以开始做输入比较了,比较完事了,清楚模型。

  所谓的variation_model的模型呢,其实是从一系列已经确认是OK的样图中,训练出2幅结果图,即上限图和下限图,也可以认为是训练出图像公差带,当要进行比较的时候,就看输入的图像的每个像素是否位于这个公差带之类,如果是,则这个点是合格的,不是,则这个像素点就是不合格的区域。

  那么在Halcon中,把这个工作就分解为了上面这一大堆函数。我们稍微来对每个函数做个解析。

  一、create_variation_model  创建模型。

  这个算子有如下几个参数:

      create_variation_model( : : Width, Height, Type, Mode : ModelID)

  这里主要是注意Type和Mode两个参数。  

  其中Type可以取'byte', 'int2', 'uint2' 这三种类型,我这里的解读是这个算子支持我们常用的8位灰度图像 和 16位的Raw图像, 16位因为有signed short和unsigned short,所有这里也有int2 和uint2两种类型。

  Mode参数有3个选择,: 'standard', 'robust', 'direct',这也是这个算子的灵魂所在,具体的做法后续再说,在创建时只是保存了他们的值,并没有做什么。

  那么创建的工作要做的一个事情就是分配内存,Halcon里的帮助文章是这样描述的:

  A variation model created with create_variation_model requires 12*Width*Height bytes of memory for Mode = 'standard' and Mode = 'robust' for Type = 'byte'. For Type = 'uint2' and Type = 'int2', 14*Width*Height are required. For Mode = 'direct' and after the training data has been cleared with clear_train_data_variation_model, 2*Width*Height bytes are required for Type = 'byte' and 4*Width*Height for the other image types.

  为什么是这样的内存,我们后续再说,接着看下一个函数。

  二、train_variation_model 训练模型

  这个算子是这个功能的最有特色的地方,他用于计算出variation_model 模型中的 ideal image和 variation image,即理想图像和方差图像。

  当Mode选择 'standard', 'robust'时,此算子有效,当Mode为'direct'无效。

  Mode为 'standard'时,训练采用求多幅平均值的方式获取理想图像以及对应的方差图像,Mode为 'robust'时,采用,求多幅图像的中间值的方式获取理想图像以及对应的方差图像。

  注意,这里的求均值和方差是针对同一坐标位置,不同图像而言的,而不是针对单一图像领域而言,这个概念一定不能能错了,比如训练5副图像,他们某一行的对应位置数据分别为:

  当选择模式为 'standard',训练结果的 ideal image 值应该是(实际还需要四舍五入求整):    

  当选择模式为 'robust',训练结果的 ideal image 值应该是:

  当选择'standard'模式,我们可以在找到一副OK图像的时候,单独把这幅图像的数据训练到variation_model模型,而如果使用'robust'方式,则必须一次性把所有的OK图像添加到训练模型中,无法动态的添加对象,但是,由于'robust'模式采用的是中值的方式,因此,其抗噪音效果要好很多。

  为什么'standard'模式可以随时添加,而'robust'只能一次性添加,其实这个也很简单,前一次求平均值的信息如果临时保存了,那么在新的OK图需要添加时,可以直接利用前一次的有关信息进行沟通,而如果是采用求中值的方式,前面的排序信息一是难以保存(数据量大),二是即使保存了,对本次排序的作用也不大。

  这个时候我们停来下分析下前面Halcon文档里的提出的variation_model模型的内存占用大小,假如我们的Type是byte类型,使用'standard'模式,那么Ideal Image占用一份Width*Height字节内存,variation image必须是浮点类型的,占用 4 * Width*Height字节内存,另外,我们能随时添加新的OK的图像,应该还需要一个临时的int 类型的数据保存累加值(虽然Ideal Image保存了平均值,但是他是已经进行了取舍了, 精度不够),这需要额外的4 * Width*Height字节内存,后面我们提到variation_model还需要有2个width * height自己大小的内存用来保存上限和下限的图像数据,因此这里就有大概 1 + 4 + 4 + 2 = 11 * width * height的内存了,还差一个,呵呵,不知道干啥的了。

  选择'robust'模式时, ideal image好说,就是取中间值,但是对于variation image,并不是普通的方差图像,在halcon中时这样描述的:The corresponding variation image is computed as a suitably scaled median absolute deviation of the training images and the median image at the respective image positions,实际上,他这里是计算的绝对中位差,即计算下面这个数的中间值了。       

         MAD=median(∣X−median(X)∣)

  这个还需要举例说明吗????

  对于使用‘standard’模式的计算优化,也是有很多技巧的,不过这个应该很多人能掌握吧。但是如果是'robust'模式,直接写求中值的方法大家应该都会,但是因为这是个小规模大批量的排序和求中值的过程,其实是非常耗时的,比如W = 1000, H=1000,如果训练20副图像,那么就是1000*1000 = 100万个20个数字的排序,而且还涉及到到一个非常严重的cache miss问题。 即这20个数字的读取每次都是跨越很大的内存地址差异的。

  如何提高这个排序的过程,我觉得在这里指令集是有最大的优势的,他有两个好处,一是一次性处理多个字节,比如SSE处理16个字节,这样我也就可以一次性加载16个字节,整体而言就少了很多次cache miss,第二,如果我需要利用指令集,则我需要尽量的避免条件判断,因此,很多稍微显得高级一点的排序都不太合适,我需要找到那种固定循环次数的最为有效,比如冒泡排序,他就是固定的循环次数。

  对于N个图像的逐像素排序求中值,一个简单的C代码如下所示:

  

  纯C代码的话,这个的效率绝对不是最高的,有很多优秀的排序算法都可以比这个快很多。但是他是最简单,也是最简洁的,最适合进行SIMD优化的。 看到中间的X循环了吗,那就是他主要的计算量所在,这个循环用指令集优化是不是很简单。

  有人说这个循环就是个典型的判断分支语句啊,你刚刚说要避免分支,这明显不就是个矛盾吗,那么我如果把这个循环这样写呢:

        

  他们结果是不是一样,还有分支吗,好了,到这一步,后面的SIMD指令应该不需要我说怎么写了吧,_mm_min_epu8 + _mm_max_epu8。

  至于median absolute deviation的中值的计算,除了需要计算MAD值之外,其他有任何区别吗? MAD不恰好也可以用byte类型来记录吗,应该懂了吧。

  三、prepare_variation_model 准备模型

    这个算子的有如下几个参数:

      prepare_variation_model( : : ModelID, AbsThreshold, VarThreshold : )

  这个算子实际上是根据前面的训练结果结合输入的 AbsThreshold和VarThreshold参数确定最终的上限和下限图像,即确认公差带。

  Halcon内部的计算公式为:

          

  i(x,y)是前面得到的Ideal Image, v(x,y)为variation image,  au/al/bu/bl即为算子的输入参数。这个没有啥好说的,具体可以看Halcon的帮助文档。

  四、 compare_variation_model 比较模型

   算子原型为:    compare_variation_model(Image : Region : ModelID : )

  经过前面的一些列操作,我们的准备工作就完成了,现在可以用来进行检测了,检测的依据如下式:  

          

  即在公差带内的图像为合格部分,否则为不合格部分。

  五、其他算子  

    clear_variation_model          --    删除模型数据,这个没啥好说的

    prepare_direct_variation_model    --    直接准备模型数据,这个在Mode设置为direct时有效,他无需经过训练,直接设置上下限数据,一般不使用

    clear_train_data_variation_model            --    清除训练数据,当我们训练完成后,那个Ideal Image 、variation image、临时数据等等都是没有用的了,都可以释放掉,只需要保留上下限的数据了。

  还有几个算子没有必要说了吧。

  总的来说,这是个比较简单的算子,实际应用中可能还需要结合模版匹配等等定位操作,然后在映射图像等,当然也有特殊场合可以直接使用的。

  我这里做了一个DEMO,有兴趣的朋友可以试用一下: https://files.cnblogs.com/files/Imageshop/Variation_Model.rar?t=1697790804&download=true

  

翻译

搜索

复制

关于Halcon中variation_model模型的快速解读。的更多相关文章

  1. Zbrush 4R7 P3中各类模型怎么快速隐藏

    在ZBrush®软件中除了遮罩功能可以对模型局部进行编辑外,我们还可以通过显示和隐藏来对模型的局部进行控制. 查看更多内容请直接前往:http://www.zbrushcn.com/jichu/xia ...

  2. 【工程应用一】 多目标多角度的快速模板匹配算法(基于NCC,效果无限接近Halcon中........)

    愿意写代码的人一般都不太愿意去写文章,因为代码方面的艺术和文字中的美学往往很难兼得,两者都兼得的人通常都已经被西方极乐世界所收罗,我也是只喜欢写代码,让那些字母组成美妙的歌曲,然后自我沉浸在其中自得其 ...

  3. HALCON中的算子大全(中英对照)

    HALCON中的算子大全(中英对照) Chapter 1 :Classification1.1 Gaussian-Mixture-Models1.add_sample_class_gmm功能:把一个训 ...

  4. ThinkPHP中的模型

    ThinkPHP中的模型 1.什么是模型(Model) 模型表示企业数据和业务规则,实际项目开发中,主要实现与数据库进行操作. 2.模型的定义规则 模型类的命名规则是除去表前缀的数据表名称,采用驼峰法 ...

  5. IdentityServer4 中文文档 -11- (快速入门)添加基于 OpenID Connect 的用户认证

    IdentityServer4 中文文档 -11- (快速入门)添加基于 OpenID Connect 的用户认证 原文:http://docs.identityserver.io/en/releas ...

  6. 【短道速滑九】仿halcon中gauss_filter小半径高斯模糊优化的实现

    通常,我们谈的高斯模糊,都知道其是可以行列分离的算法,现在也有着各种优化算法实现,而且其速度基本是和参数大小无关的.但是,在我们实际的应用中,我们可能会发现,有至少50%以上的场景中,我们并不需要大半 ...

  7. 在 Sublime Text 2 中使用 SFTP 插件快速编辑远程服务器文件

    在 Sublime Text 2 中使用 SFTP 插件快速编辑远程服务器文件 开源程序 浏览:29555 2013年05月02日 文章目录[隐藏] 常见的工作流程 SFTP 安装和使用方法 第一步: ...

  8. 总结一下一般游戏中3D模型各种勾边方法遇到的工程性问题

    以前做过简单的rim light勾边,几何勾边,这次又做了后处理的勾边,工程化的时候,都遇到很多问题,简单总结一下. 首先是火炬之光勾边效果,类似轮廓光的实现,简单的卡通渲染也是通过类似的算法加采样色 ...

  9. 15SpringMvc_在业务控制方法中写入模型变量收集参数,且使用@InitBind来解决字符串转日期类型

    之前第12篇文章中提到过在业务控制方法中写入普通变量收集参数的方式,也提到了这种凡方式的弊端(参数很多怎么办),所以这篇文章讲的是在业务控制方法中写入模型变量来收集参数.本文的案例实现的功能是,在注册 ...

  10. ThinkPHP中的模型二

    ThinkPHP中的模型 1.为什么要创建数据对象 案例:使用ThinkPHP完成部门管理 ① 设计数据库 ② 创建Dept控制器 路径:./Application/Admin/Controller创 ...

随机推荐

  1. Java 集合框架体系简介

    为什么要使用集合 存储多个数据可以使用数组,但由于数组在内存中是连续存储的,所以会有一些限制.比如数组在创建时就要指定长度,即可以容纳的元素个数,且指定后无法更改:数组在创建时需要指定元素的类型,并且 ...

  2. 【笔试实战】LeetCode题单刷题-编程基础 0 到 1【一】

    1768. 交替合并字符串 题目链接 1768. 交替合并字符串 题目描述 给你两个字符串 word1 和 word2 .请你从 word1 开始,通过交替添加字母来合并字符串.如果一个字符串比另一个 ...

  3. WebAPI公开接口请求签名验证

    前言 现在的系统后端开发的时候,会公开很多API接口 对于要登录认证后才能访问的接口,这样的请求验证就由身份认证模块完成 但是也有些接口是对外公开的,没有身份认证的接口 我们怎么保证接口的请求是合法的 ...

  4. Qt源码阅读(五)-deleteLater

    Qt deleteLater作用及源码分析 个人经验总结,如有错误或遗漏,欢迎各位大佬指正 在本篇文章中,我们将深入分析源码,探讨deleteLater的原理. deleteLater是Qt框架提供的 ...

  5. Html转换PDF(Java实用版)

    前言: 在工作当中,遇到了需要把HTML页面转化为PDF文档,有很多中实现,如下进行一个对比,大家个借鉴去进行使用 各实现对比表 于Windows平台进行测试: 此博客仅基于IText和基于WKHtm ...

  6. java volatile是如何保证可见性的?

    lock前缀指令干的事. volatile 修饰的变量在进行写操作时会多出一条如下的汇编指令: lock addl $0x0,(%esp) volatile就是靠这个lock前缀指令去实现可见性的,当 ...

  7. DNS与CDN技术

    参考链接: CDN原理简单介绍 浅析:DNS解析和CDN加速 DNS报文格式解析

  8. 2021-7-29 MySql多表查询详解

    多表连接 左连接:返回第一张表的所有数据项然后拼接第二张表(左表全有,右表对应左表才有) 右连接:返回第二张表的所有数据项然后拼接第一张表(右表全有,左表对应右表才有) 内连接:返回两张表数据相等的数 ...

  9. python命令行解析模块argparse

    argparse是Python标准库中推荐的命令行解析模块 code01: tmp.py import argparse parser = argparse.ArgumentParser(descri ...

  10. vscode snnipet of python

    { // Place your snippets for python here. Each snippet is defined under a snippet name and has a pre ...