VM的模块由界面层,底层这两大块组成,分别有自己对应的DLL。以圆查找为例:
图
1 模块概念与实际文件对应
IMVSCircleFindModu.dll为模块底层,实现具体的圆查找算法逻辑。
IMVSCircleFindModuCS.dll为模块界面层,为二次开发者提供可以使用的模块类:IMVSCircleFindModuTool类。
第二部分主要讲解模块底层如何与XML配合显示和设置配置数据,与模块框架配合获取输入,编写计算逻辑,并把计算结果设置给模块框架从而进一步显示到界面上。
以自定义一个平移旋转模块为例:
图
2 平台旋转工具
通过模块生成工具来生成模块:
图
3 配置输入输出
图
4 配置参数
依次点击生成XML,生成C++工程,生成C#工程,得到如下3个文件夹。
图
5 生成物
分别是模块的XML,模块底层代码工程和模块界面代码工程。
模块底层是使用C++语言开发的,打开工程可看见:
图
6 底层模块代码
● CreateModule: 模块框架加载模块时,创建模块类实例时调用。
● DestroyModule: 模块框架卸载模块时,销毁模块类实例时调用。
● Init: 在CreateModule时调用,做内部成员的初始化赋值。
● Process: 在模块运行时调用,以该平移旋转模块为例,平移旋转的具体计算代码应放在这里面。
● GetParam: 配置界面显示时调用,获取界面显示的参数值。
● SetParam: 配置参数修改时调用,界面向底层下发新的参数值。
参数配置,在平移旋转这个示例中,参数有DeltaX,DeltaY和DeltaR分别是需要偏移的X,Y值和旋转的角度。生成工具生成了界面与底层代码两部分。
参数配置界面XML在MoveAndRotateAlgorithmTab.xml,如下图:
图
7 参数配置界面XML部分
在底层模块的GetParam与SetParam中有与界面对应的内容:
图
8 参数配置底层部分
要点是界面的Name要与底层的szParamName对应上,比如:DeltaX。也可以按照这个规则手动在界面上添加新的参数,并在底层添加对应代码做设置和获取。上述代码中DeltaX的值被设置进了m_fDeltaX的成员变量中暂存。
在参数配置完成后,模块运行,此时框架会调用Process,默认生成的Process为空,是没有代码逻辑的,需要开发人员填充,如下:
图
9 处理函数代码
第一步为获取输入,模块输入在MoveAndRotate.xml之中,如下图:
图
10 输入输出定义XML
可见,模块生成工具已经在输入中填入了XIn,YIn,RIn这三个自定义输入和InputImage输入图片,InputROI输入ROI这两个基础输入。
在Process中需要获取到XIn,YIn,RIn这三个数值,并结合配置的偏移量进行处理。此时需要用到模块框架提供的输入获取函数VmModule_GetInputScalar_32f,框架提供的基本函数可见VmModule_IO.h。如下:
图
11 获取输入
要点是输入的类型要与获取函数类型对应,本例中XIn是float类型,对应的获取函数是VmModule_GetInputScalar_32f。还有Int,String等的对应函数接口。
VmModule_GetInputScalar_32f的第二个参数xmlName要与MoveAndRotate.xml中的Filter Name相对应。
第二步为逻辑计算,本例中逻辑非常简单,就是把输入量加上配置的偏移量即可。如下:
图
12 算法处理
第三步输出计算结果,在定义输入输出的XML中,我们已经定义了模块的输出名称,如下:
图
13 输出XML定义
可见输入中包含了XOut, YOut, ROut这三个自定义输出和ModuStatus模块运行结果状态,OutputImage输出图片, ROI框这三个基础输出。
在Process中把计算结果关联到XOut, YOut, ROut上的代码如下:
图
14 设置模块输出
与输入一样,要注意输出函数与fResX的类型对应。nProcessStatus为算法计算的状态,本例中都输出的OK,但在其它场景中,有可能算法计算失败,此时应输出1(NG)。
还需注意VmModule_OutputScalar_32f的第4个参数xmlName与MoveAndRotate.xml中的Output里Filter Name相对应。
模块底层的逻辑就基本编写完成了。