前言
VM推出了进行二次开发的SDK(Software Development Kit),VM SDK开发理念是以极少的代码实现图像算法的二次开发集成,从而降低视觉开发人员对视觉处理逻辑代码的维护成本。本文即介绍如何用VM SDK和C++进行联合开发。
开发过程
1.1 方案加载
VM二次开发方案加载:方案后缀为sol(一般建议在VM软件中创建好算法方案,在二次开发中调用),路径为绝对路径。
//创建方案指针
IVmSolution* m_pVmSol;
//加载方案
m_pVmSol = LoadSolution(strPath.c_str(), "");
加载完成后就可以对方案就行操作了,当然VM SDK也提供了用来显示方案的控件(VmProcedureConfigControl 流程配置控件和VmMainViewCongfigControl 主界面控件),无需绑定,只要界面中有这两个中任意控件并初始化,加载完方案后会自动绑定显示。如图所示:
1.2 参数调整
VM二次开发为修改算法参数提供了两种方式:
1.2.1方式1: 用自带的参数配置控件( VmParamsConfigControl 参数配置控件、VmParamsConfigWithRenderControl 参数配置带渲染控件)调参。控件绑定模块代码示例如下:
auto pObject = (CModuParamsBase*)(*m_pVmSol)[CT2A(_T("流程1.圆查找1"))];
m_ParamsRender.SetParamsInfo(pObject, "");
绑定完成控件就会自动填充当前模块的参数配置信息,进行修改即可(注意这里修改的参数并不会实时保存到方案文件里,需要调用方案保存接口才会保存)。
1.2.2方式2: 调用工具类的模块参数对象(ModuParams)提供的接口或Public属性(可以在开发文档中查阅、也可以在VS中进入相关参数类的定义进行查阅)来修改。示例代码如下:
auto pObject = (IMVSCircleFindModuTool*)(*m_pVmSol)[CT2A(_T("流程1.圆查找1"))];
auto pParams = pObject->GetParamObj();
pParams->RadNum = 20;
1.3 流程执行
VM算法执行方式有多种:二次开发仍然支持VM中配置的硬触发和通讯触发,同时提供了Run接口来支持软触发。软触发示例代码如下:
m_pVmSol->Run();
上述的方案Run接口会触发所有流程同时执行一次,当然也提供了单个控制流程/模块执行的方式,需要先实例化需要Run的流程/模块对象然后调用该对象的Run接口即可触发流程/模块执行,示例代码如下:
auto m_vmPrc = (IVmProcedure*)(*m_pVmSol)[CT2A(str1.GetString())];
m_vmPrc->Run();
IMVSCircleFindModuTool* pObject2 = (IMVSCircleFindModuTool*)(*m_pVmSol)["流程1.圆查找1"];
pObject2 ->Run();
1.4 结果获取
1.4.1 渲染结果获取:
方式1: VM SDK提供了渲染控件(vmRenderControl),可以通过给该控件直接绑定流程/模块对象资源来实现相应对象显示设置配置的渲染。示例代码如下:
//流程对象
auto pObject = (IVmProcedure*)(*m_pVmSol)[CT2A(_T(“流程1”))];
pCirFindObject = pObject->GetParamObj();
//模块参数对象
pCirFindObject = (CModuParamsBase*)(*m_pVmSol)[ CT2A(_T(“流程1.圆查找1”))];
//绑定
m_RenderCtr.SetParamsInfo(pCirFindObject);
需要注意的是:这里的渲染绑定是动态绑定,只需在流程/方案执行前绑定一次即可,后续流程/方案运行时渲染界面会实时更新对应绑定对象的渲染结果(对应的是模块/流程的显示设置信息:图像、形状信息和文字信息)。
方式2: 自己获取图形或文字数据在VM SDK提供的渲染控件上绘制。示例代码如下:
auto pObject = (ImageSourceModuleTool*)(*m_pVmSol)["流程1.图像源1"];
if (NULL == pObject) return;
auto pResult = pObject->GetResult();
if (NULL == pResult) return;
// 设置图像数据
m_RenderCtr.SetImageSourceData(&(pResult->GetImageData()));
//获取图像结果
IMVSCircleFindModuTool* pObject2 = (IMVSCircleFindModuTool*)(*m_pVmSol)["流程1.圆查找1"];
if (NULL == pObject2) return;
CircleFindResults* pResult2 = pObject2->GetResult();
if (NULL == pResult2) return;
// 设置圆形数据
CircleEx stCir = { 0 };
stCir.CenterX = pResult2->GetCircleCenter().fX;
stCir.CenterY = pResult2->GetCircleCenter().fY;
stCir.MajorRadius = pResult2->GetCircleRadius();
stCir.MinorRadius = pResult2->GetCircleRadius();
//设置颜色
int nArgb = 0;
nArgb += 100 << 16;
nArgb += 200 << 8;
nArgb += 150;
stCir.Color = nArgb;
stCir.FillColor = nArgb;
stCir.Opacity = 1;
stCir.StrokeThickness = 1;
//绘图
m_RenderCtr.SetCircle(&stCir);
绘制效果如下图所示:
当前VM渲染控件支持绘制的形状结构体有点、点集、线、圆、圆环以及多边形等,具体可以查看Shape类。绘制多边形示例代码如下:
// 绘制图形
int CMFCApplication5Dlg::DrawShape()
{
// TODO: 在此处添加实现代码.
CString strTemp;
try
{
PolygonEx polygon;
polygon.PolygonPointNum = 5;
PointFEx point[5];
point[0].X = 50; point[0].Y = 50;
point[1].X = 50; point[1].Y = 550;
point[2].X = 325; point[2].Y = 650;
point[3].X = 600; point[3].Y = 550;
point[4].X = 600; point[4].Y = 50;
polygon.PolygonPointListPtr = point;
int nArgb = 0;
nArgb += 100 << 16;
nArgb += 200 << 8;
nArgb += 150;
polygon.Color = nArgb;
polygon.FillColor = nArgb;
polygon.Opacity = 2;
polygon.StrokeThickness = 2;
m_RenderCtr.SetPolygon(&polygon, true);
}
catch (CVmException ex)
{
strTemp.Format(_T("%d"), ex.GetErrorCode());
m_VmLog.InsertString(0, _T("File Code:") + strTemp);
}
return 0;
}
绘制效果如下图所示:
1.4.2 数据结果获取: 需要通过对应工具类的结果对象类获取。
方式1: 可以在搭建流程时将流程内的模块结果都绑定到流程的输出设置里,然后统一使用流程对象提供的结果获取接口进行获取。部分接口示例如下:
//通过流程获取结果
CString str;
m_Combox1.GetLBText(m_Combox1.GetCurSel(), str);
auto pObject1 = (IVmProcedure*)(*m_pVmSol)[CT2A(str.GetString())];
auto pResult1 = pObject1->GetResult();
auto outStr = pResult1->GetOutputFloat("out").pFloatVal[0];
str.Format(_T("ProcedureResult:%.3f"), outStr);
方式2: 通过每个工具类的模块结果对象(ModuResult)获取,示例代码如下:
//通过模块获取结果
IMVSCircleFindModuTool* pObject2 = (IMVSCircleFindModuTool*)(*m_pVmSol)["流程1.圆查找1"];
if (NULL == pObject2) return;
CircleFindResults* pResult2 = pObject2->GetResult();
if (NULL == pResult2) return;
CircleEx stCir = { 0 };
stCir.CenterX = pResult2->GetCircleCenter().fX;
stCir.CenterY = pResult2->GetCircleCenter().fY;
stCir.MajorRadius = pResult2->GetCircleRadius();
stCir.MinorRadius = pResult2->GetCircleRadius();
总结
多参考官方提供的开发文档及资源,基本上能实现大部分的开发需求。
附开发资源路径:
开发手册:VisionMaster4.2.0\Development\V4.x\Documentations
开发案例:VisionMaster4.2.0\Development\V4.x\Samples
V社区(VM开发者技术园地)链接:https://www.v-club.com/home
资料荟萃链接:https://one.hikvision.com/#/link/XcwZ3QdfwYzO8f6TqlI3 提取密码:kGHn(包含讲义、问答集FAQ和软件Demo等,无需注册,直接下载)