抓图系统设计
抓图系统设计
难点
- 主要步骤
- 抓图
- 抓图中的后处理
- PackView涉及到的后处理
- 参数复杂性,体现在参数有不同来源 –》由具体实现决定
- 来自系统配置文件
- 来自calibration或者用户可以修改的系统数据
- 来自learn的record或者criteria
- 不同应用会有完全不同的 –》由具体实现决定
- 参数配置方式
- 抓图和后处理逻辑不同
- 我们的目的又想最优化抓图和后处理时间
- 我们又想尽量配置这些容易变化的东西,以便快速反应市场需求 –》写一个脚本的实现,或者
- 有些矛盾的极致要求
- 两次计算可以share中间和最终内存
- 能够多次并行计算,这样又要求数据独立
- 一个计算分为多个步骤。某些步骤可以并行计算。某些步骤不需要并行计算
- 又想减少内存使用,中间数据想用完就删
- –》思路,
- 控制要缓存的数据。只有那些关键节点上的数据需要缓存。
- 让用户定义关键节点,一般来说包括,grab结果,
packview结果,grab freezed的输入,packview freezed的输入 - 缓存的数据要记录输入参数
- 关于接口,能否统一定义为grab只接受抓图参数,而packview才接受后处理参数?
- 底层可以这样
- 但高层不是这样的,由于高层packview需要模块无关,很多底层packview的参数在高层需要提前bind好,这就意味着高层的packview不收任何参数,或者只收一个roi参数
- 同时有要求尽快处理的需求,希望抓完图尽快处理,所以需要抓图的时候就能trigger到后处理。这对于现在的同步系统来说,就意味着开多线程packview,或者修改抓图模块,以便在抓图的时候顺便做后处理
- 具体做法上,就意味着不同用法要继承一个基本的grabproxy接口
- 现在是应用层定义不同的grabproxy接口:IOC,3D。但定义的并不统一,并且不支持任意组合,所以很难重用
- 应用层定义不同的grabproxy接口面临一个问题是。
- 不同应用都要分别定义类似的接口,这个是小问题
- 应用层定义不同的grabproxy接口一般是在insp。没有统一的办法同时支持live video, learn
- 关于GAA接口参数设计,如何在特殊的抓图参数和后处理不停的增加的情况下,不会增加接口复杂度?
- 一般思路是将变化的地方以统一的方式model
- 比如model后处理为一系列的操作。每个操作有输入输出。操作之间的输入输出有依赖关系
- 比如model抓图为unit layer,optics layer,sensor layer??
- 关于应用层接口设计,如何在有好多不同的应用逻辑的情况下,不会增加接口复杂度?
- 好多不同的应用逻辑
- 参数来源多变
- 同一个应用,在不同情况下(Cal, Learn, Insp, Live video)用法差异很大
- 如何model为统一的方式?
- 把参数来源model为具体实现内部逻辑,不在外部接口model它 –》Prefer this
- 用Optics file配置参数来源 –》这是一种具体实现
- 统一参数来源–》这是另外一种具体实现
- 好多不同的应用逻辑
问题分析
如果把参数来源model为具体实现,那这里的这些问题其实不是问题了
问题本质上可以归结为一个计算有很多步骤,每一步有输入输出,下一步的输入可能依赖于上一步。
这个计算会被trigger很多次,有一些输入参数在多次运算是一样的,所以部分 步骤不需要重新计算
问题可以归结为一个优化问题,也就是计算的数据依赖分析。可以想象一个调度系统缓存住上一次的输入,和中间输出,在来了一个新的参数的时候,分析那些变化的参数和不变的参数,进而有选择性的只计算需要的部分
functional programming,和数据流图比较适合做这个分析
都说pytorch是动态分析构建计算图?
以上难度较大。现考虑手动构建
關鍵假設。
一次抓圖一個設置,出來一張圖
关键概念
grabber。model為相機,一般為 per optics。為字符串
grabusage。model為用途,一般為learn,insp,etc相關參數。有機會有usage相關參數,比如appl record。為kv。參數可選,默認為當前設置
grabsetting,model為每次抓圖都不同的參數,為kv。一般為grabset,roi。有機會有usage相關參數,比如object height
高层API接口
所谓高层接口意味着这些函数的用户是
- 应用模块,
- PR接口
他们只会用最简单的方式PackView,最多也就是有个ROI参数,或者少数自定义参数,如object height
接口类似于file api,但有些关键不同
file api 不允许多次同时open一个文件,而grab api可以
file api open之后的handle要进行的是read之类操作,而grab api open之后的grabber要进行的是grab操作
c接口
fp=gopen(grabbername, grabusage)
h=ggrab(fp,grabsetting)
gwaitexpo(h)
gpackview(h, packsetting)
gfree(h)
gclose(fp)
cpp接口
class GrabHandleBase{
void packViewAsync(roi, map<string, any> const& packArgs, callback);
}
class GrabBase{
// grabArgs: 每次抓图用户需要传的参数,不包括系统内部数据。比如For HDOA2D, grabArgs={“ObjectHeight”},但不应该有IST Record
shared_ptr<opticsGrabHandleBase> Grab(Grabset, grabPara, map<string, any> const& grabArgs);
}
// grabusage: can be inspect, learn, live video, etc
// usage相关参数: 对于grabusage=inspect, usage相关参数 = {record id}
shared_ptr<opticsGrabHandleBase> gopen(grabbername, grabusage, usage相关参数)
use case
HDOA 有两种用法
- 用法1: grabArgs = {“ObjectHeight”}, packArgs={}
- 用法2: grabArgs = {}, packArgs={“ObjectHeight”}
这两种用法会同时用吗?
底层API接口
这里的底层是说GAA模块。与高层不同,底层可以有不同的设计
- 能否将抓图和后处理逻辑分离?
- 有些可以,比如一般的image correction
- 不完全可以,比如HDOA的抓图和后处理紧密结合,不容易分离
- 底层api设计可以根据抓图和后处理的本质调整接口参数,在接口设计上有更大的操作空间
- 底层的关键是实现基本函数(比如HDOA),但不意味着用同一个函数实现
实现
實現可以為應用相關,也可以通用化,如果有可能。可以写几个,config,lua,和hdoa2d
API接口的实现可以包括
- c plugin: 比如hdoa2d,要實現一個特有的hdoa grabber。grabber自己看配置。insp的時候grabusage為insp,grabsetting為grabset,roi,以及objectheight
- 脚本plugin
- 配置文件: 配置文件为API接口的一种实现。用来方便应用工程师基于业务逻辑来配置用法
grabber工厂实现:
入口还是配置文件,在opticsfile里面配置为mode
如果mode为dll名字,那么load cplugin
如果mode为脚本名字,那么用脚本plugin
。。。
配置文件
脚本plugin
可以考虑的思路
- 每次抓图不需要运行脚本。
- 需要运行一次脚本,output的是编译之后的c代码,这样以后才不需要脚本引擎的帮助
- 如果要做成很general,难度比较大
- 如果要做成general,其实相当于自己做一个jit, or script engine。做出来的反而不如利用lua
- 每次抓图运行脚本
- 这个比较好做
- concern:速度和c比不够快
- idea:先用script快速實現用户需求,如果速度不夠再針對性用c加速