脚本实例化模块操作
有些情况vm使用需要灵活一些,这是就需要在常规vm逻辑之外对模块进行一些操作,这时根据VMSDK进行类似于二次开发的动作,在脚本中实例化对应模块SDK或者通过官网教程自定义封装一个新模块调用原有VMSDK再加上一些新的定制功能,来响应不同需求
步骤(脚本实例化)
自定义开发模块步骤如下,官网v社区:
https://www.v-club.com/home/article/1189
https://www.v-club.com/home/article/1353
https://www.v-club.com/home/article/1411
注意事项:
https://www.v-club.com/home/article/1266
脚本实例化:
1、【脚本引用】脚本->编辑程序集->应用程序集
ps:实际要应用SDK中的库文件\VisionMaster4.3.0\Development\V4.x\ComControls\Assembly
一般除了目标模块的库文件,还有VM.Core.dll、VM.PlatformSDKCs.dll、VMControls.Baselnterface.dll、VMControls.Interface.dll是要引用的
2、【目标库文件】如果不熟悉模块对应的库文件名称,在安装路径\VisionMaster4.3.0\Applications\Module(sp)\x64找不到对应模块的库文件,界面选中目标模块Cltl + M 自动索引找到对应名称,实际还是要在【1ps】中的SDK库文件中找到目标库文件
3、【复制到脚本库路径下】对应脚本Cltl + M 将库文件复制到DLL文件夹下
4、【脚本中引用】例如引用高精度匹配
using VM.Core;
using VM.PlatformSDKCS;
using IMVSHPFeatureMatchModuCs;
脚本实例化例子片段1
#代码更新标定点坐标后标定生效的方法
VmProcedure procedure = VmSolution.Instance["流程1"] as VmProcedure;
var nPointCalib = procedure["N点标定1"] as IMVSNPointCalibModuCs.IMVSNPointCalibModuTool;
nPointCalib.ModuParams.DoClearPoint();//设置前执行一次清空标定点
List<VM.PlatformSDKCS.PointF> imageList = new List<VM.PlatformSDKCS.PointF>();
List<VM.PlatformSDKCS.PointF> wordList = new List<VM.PlatformSDKCS.PointF>();
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
imageList.Add(new VM.PlatformSDKCS.PointF((float)i, (float)j));
wordList.Add(new VM.PlatformSDKCS.PointF(i * count, j * count));
}
}
nPointCalib.ModuParams.ImagePoint = imageList;
nPointCalib.ModuParams.PhysicalPoint = wordList;
if (procedure != null)
{
procedure.Run();
}
脚本实例化例子片段2
# 可以通过模块的RoiManager类设置模块ROI;
# 注意:通过该方式设置的ROI仅当次运行生效;
var prc = VmSolution.Instance["流程1"] as VmProcedure;
IMVSCircleFindModuTool tool = (IMVSCircleFindModuTool)prc["圆查找1"];
RectBox rectBox = new RectBox(new VM.PlatformSDKCS.PointF(1000, 1000), 500, 500, 0);
tool.ModuParams.ModuRoiManager.RoiRectangle = rectBox;//代码设置ROI
prc.Run();
脚本实例化例子片段3
#可以通过通用接口SetBinaryData()设置模块ROI;
#注意:通过该方式设置的ROI二次开发进程运行期间永久生效,需要保存进方案需调用保存方案接口;
try
{
// 设置ROI
RoiBox roiBox = new RoiBox();
roiBox.bRoiType = (byte)RoiType.ROI_TYPE_BOX;
roiBox.fCenterX = (float)(rect.CenterPoint.X / vmRenderControl1.ImageSource.Width); // 需要使用像素值X/图像宽获得归一化值,例如0.5表示图像中心点
roiBox.fCenterY = (float)(rect.CenterPoint.Y / vmRenderControl1.ImageSource.Height); // 需要使用像素值Y/图像高获得归一化值,例如0.5表示图像中心点
roiBox.fWidth = (float)(rect.Width / vmRenderControl1.ImageSource.Width); // 同上
roiBox.fHeight = (float)(rect.Height / vmRenderControl1.ImageSource.Height); // 同上
roiBox.fAngle = (float)rect.Angle; // 需要使用矩形框的角度(不是弧度)
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(roiBox));
Marshal.StructureToPtr(roiBox, ptr, false);
VmModule module = (VmModule)VmSolution.Instance[ModuleName];
uint moduleId = module.ID;
ServerSDKManager.serverSDKManager.mModuleManager.SetBinaryData(moduleId, "RoiType", ptr, Marshal.SizeOf(roiBox));
Marshal.FreeHGlobal(ptr);
ptr = IntPtr.Zero;
}
catch (MvdException ex)
{
string strMsg = "ErrorCode: 0x" + ex.ErrorCode.ToString("X") + ", message is : " + ex.Message + "\r\n";
}
catch (VmException ex)
{
string strMsg = "ErrorMessage is " + ex.errorMessage + " ErrorCode is " + Convert.ToString(ex.errorCode, 16);
}
catch (Exception ex)
{
string strMsg = Convert.ToString(ex);
}
脚本实例化例子片段4
#设置多边形ROI方法示例:
try
{
// 设置ROI
RoiPolygon roiPolygon = new RoiPolygon();
roiPolygon.bRoiType = (byte)RoiType.ROI_TYPE_POLYGON;
roiPolygon.nVertexNum = (uint)polygon.PolygonPoints.Count;
roiPolygon.stVertexPoints = new RoiPoint[ImvsSdkDefine.IMVS_MAX_POLYGON_VERTEX_NUM];
for (int i = 0; i < roiPolygon.nVertexNum; i++)
{
roiPolygon.stVertexPoints[i].fX = (float)(polygon.PolygonPoints[i].X / vmRenderControl1.ImageSource.Width);
roiPolygon.stVertexPoints[i].fY = (float)(polygon.PolygonPoints[i].Y / vmRenderControl1.ImageSource.Height);
}
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(roiPolygon));
Marshal.StructureToPtr(roiPolygon, ptr, false);
int nDataLen = (int)(Marshal.SizeOf(roiPolygon) - (ImvsSdkDefine.IMVS_MAX_POLYGON_VERTEX_NUM - roiPolygon.nVertexNum) * Marshal.SizeOf(roiPolygon.stVertexPoints[0]));
VmModule module = (VmModule)VmSolution.Instance[ModuleName];
uint moduleId = module.ID;
//if (!(polygon.UseType == ROIUseType.Avoid))
ServerSDKManager.serverSDKManager.mModuleManager.SetBinaryData(moduleId, "RoiType", ptr, nDataLen);
//else
//ServerSDKManager.serverSDKManager.mModuleManager.SetBinaryData(moduleId, "ExternRoiType", ptr, nDataLen);
Marshal.FreeHGlobal(ptr);
ptr = IntPtr.Zero;
}
catch (MvdException ex)
{
string strMsg = "ErrorCode: 0x" + ex.ErrorCode.ToString("X") + ", message is : " + ex.Message + "\r\n";
}
catch (VmException ex)
{
string strMsg = "ErrorMessage is " + ex.errorMessage + " ErrorCode is " + Convert.ToString(ex.errorCode, 16);
}
catch (Exception ex)
{
string strMsg = Convert.ToString(ex);
}
脚本实例化例子片段5
#设置直线卡尺ROI方法示例:
try
{
// 设置ROI
RoiLineCaliper roiLineCaliper = new RoiLineCaliper();
roiLineCaliper.bRoiType = (byte)RoiType.ROI_TYPE_LINECALIPER;
roiLineCaliper.fStartX = (float)(lineCaliper.StartPoint.X / vmRenderControl1.ImageSource.Width); // 需要使用像素值X/图像宽获得归一化值,例如0.5表示图像中心点
roiLineCaliper.fStartY = (float)(lineCaliper.StartPoint.Y / vmRenderControl1.ImageSource.Height); // 需要使用像素值Y/图像宽获得归一化值,例如0.5表示图像中心点
roiLineCaliper.fEndX = (float)(lineCaliper.EndPoint.X / vmRenderControl1.ImageSource.Width); // 需要使用像素值X/图像宽获得归一化值,例如0.5表示图像中心点
roiLineCaliper.fEndY = (float)(lineCaliper.EndPoint.Y / vmRenderControl1.ImageSource.Height); // 需要使用像素值Y/图像宽获得归一化值,例如0.5表示图像中心点
roiLineCaliper.fWidth = (float)(lineCaliper.CaliperWidth / vmRenderControl1.ImageSource.Width); // 同上
roiLineCaliper.fHeight = (float)(lineCaliper.CaliperHeight / vmRenderControl1.ImageSource.Height); // 同上
roiLineCaliper.fAngle = (float)(lineCaliper.CaliperRotateAngle);
roiLineCaliper.nNum = 10; // 卡尺数量
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(roiLineCaliper));
Marshal.StructureToPtr(roiLineCaliper, ptr, false);
VmModule module = (VmModule)VmSolution.Instance[ModuleName];
uint moduleId = module.ID;
ServerSDKManager.serverSDKManager.mModuleManager.SetBinaryData(moduleId, "RoiType", ptr, Marshal.SizeOf(roiLineCaliper));
Marshal.FreeHGlobal(ptr);
ptr = IntPtr.Zero;
}
catch (MvdException ex)
{
string strMsg = "ErrorCode: 0x" + ex.ErrorCode.ToString("X") + ", message is : " + ex.Message + "\r\n";
}
catch (VmException ex)
{
string strMsg = "ErrorMessage is " + ex.errorMessage + " ErrorCode is " + Convert.ToString(ex.errorCode, 16);
}
catch (Exception ex)
{
string strMsg = Convert.ToString(ex);
}
脚本实例化例子片段6
#设置圆卡尺ROI方法示例:
try
{
// 设置ROI
RoiCircleCaliper roiCircleCaliper = new RoiCircleCaliper();
roiCircleCaliper.bRoiType = (byte)RoiType.ROI_TYPE_CIRCLECALIPER;
roiCircleCaliper.fCenterX = (float)(circleCaliper.CenterPoint.X / vmRenderControl1.ImageSource.Width); // 需要使用像素值X/图像宽获得归一化值,例如0.5表示图像中心点
roiCircleCaliper.fCenterY = (float)(circleCaliper.CenterPoint.Y / vmRenderControl1.ImageSource.Height); // 需要使用像素值Y/图像高获得归一化值,例如0.5表示图像中心点
roiCircleCaliper.fWidth = (float)(circleCaliper.CaliperWidth / vmRenderControl1.ImageSource.Width); // 同上
roiCircleCaliper.fHeight = (float)(circleCaliper.CaliperHeight / vmRenderControl1.ImageSource.Height); // 同上
roiCircleCaliper.fOutterRadius = (float)(circleCaliper.Radius / vmRenderControl1.ImageSource.Width); // 同上
roiCircleCaliper.fStartAngle = 0.0f; // 底层就是设0
roiCircleCaliper.fEndAngle = 0.0f; // 底层就是设0
roiCircleCaliper.nNum = 10; // 卡尺数量
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(roiCircleCaliper));
Marshal.StructureToPtr(roiCircleCaliper, ptr, false);
VmModule module = (VmModule)VmSolution.Instance[ModuleName];
uint moduleId = module.ID;
ServerSDKManager.serverSDKManager.mModuleManager.SetBinaryData(moduleId, "RoiType", ptr, Marshal.SizeOf(roiCircleCaliper));
Marshal.FreeHGlobal(ptr);
ptr = IntPtr.Zero;
}
catch (MvdException ex)
{
string strMsg = "ErrorCode: 0x" + ex.ErrorCode.ToString("X") + ", message is : " + ex.Message + "\r\n";
}
catch (VmException ex)
{
string strMsg = "ErrorMessage is " + ex.errorMessage + " ErrorCode is " + Convert.ToString(ex.errorCode, 16);
}
catch (Exception ex)
{
string strMsg = Convert.ToString(ex);
}
脚本实例化例子片段7
#设置圆弧卡尺ROI方法示例:
try
{
// 设置ROI
RoiSectorCaliper roiSectorCaliper = new RoiSectorCaliper();
roiSectorCaliper.bRoiType = (byte)RoiType.ROI_TYPE_SECTORCALIPER;
roiSectorCaliper.fStartX = (float)(sectorCaliper.StartPoint.X / vmRenderControl1.ImageSource.Width); // 需要使用像素值X/图像宽获得归一化值,例如0.5表示图像中心点
roiSectorCaliper.fStartY = (float)(sectorCaliper.StartPoint.Y / vmRenderControl1.ImageSource.Height); // 需要使用像素值Y/图像宽获得归一化值,例如0.5表示图像中心点
roiSectorCaliper.fEndX = (float)(sectorCaliper.EndPoint.X / vmRenderControl1.ImageSource.Width); // 需要使用像素值X/图像宽获得归一化值,例如0.5表示图像中心点
roiSectorCaliper.fEndY = (float)(sectorCaliper.EndPoint.Y / vmRenderControl1.ImageSource.Height); // 需要使用像素值Y/图像宽获得归一化值,例如0.5表示图像中心点
roiSectorCaliper.fRadius = (float)(sectorCaliper.Radius / vmRenderControl1.ImageSource.Width); // 同上
roiSectorCaliper.fWidth = (float)(sectorCaliper.CaliperWidth / vmRenderControl1.ImageSource.Width); // 同上
roiSectorCaliper.fHeight = (float)(sectorCaliper.CaliperHeight / vmRenderControl1.ImageSource.Height); // 同上
roiSectorCaliper.nNum = 10; // 卡尺数量
if (sectorCaliper.IsLargeArc) //是否大圆弧
{
roiSectorCaliper.nLargeArc = 1;
}
else
{
roiSectorCaliper.nLargeArc = 0;
}
if (sectorCaliper.IsClockwise) //是否顺时针方向
{
roiSectorCaliper.nClockWise = 1;
}
else
{
roiSectorCaliper.nClockWise = 0;
}
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(roiSectorCaliper));
Marshal.StructureToPtr(roiSectorCaliper, ptr, false);
VmModule module = (VmModule)VmSolution.Instance[ModuleName];
uint moduleId = module.ID;
ServerSDKManager.serverSDKManager.mModuleManager.SetBinaryData(moduleId, "RoiType", ptr, Marshal.SizeOf(roiSectorCaliper));
Marshal.FreeHGlobal(ptr);
ptr = IntPtr.Zero;
}
catch (MvdException ex)
{
string strMsg = "ErrorCode: 0x" + ex.ErrorCode.ToString("X") + ", message is : " + ex.Message + "\r\n";
}
catch (VmException ex)
{
string strMsg = "ErrorMessage is " + ex.errorMessage + " ErrorCode is " + Convert.ToString(ex.errorCode, 16);
}
catch (Exception ex)
{
string strMsg = Convert.ToString(ex);
}
脚本实例化例子片段8
#设置多ROI方法示例,注:只针对部分支持多ROI模块生效。
try
{
string strMsg = "";
//计算需要申请的内存空间,以多矩形ROI为例
int roiSize = 0;
foreach (var item in roiList)
{
if (!(item is IRectROI))
{
strMsg = "请输入正确的ROI";
return 0;
}
if (item is IRectROI rect)
{
roiSize += Marshal.SizeOf(new RoiBox());
}
}
IntPtr ptr = Marshal.AllocHGlobal(roiSize);
//内存拼接
int ptrLocation = 0;
foreach (var item in roiList)
{
if (item is IRectROI rect)
{
RoiBox roiBox = new RoiBox();
roiBox.bRoiType = (byte)RoiType.ROI_TYPE_BOX;
roiBox.fCenterX = (float)(rect.CenterPoint.X / vmRenderControl1.ImageSource.Width); // 需要使用像素值X/图像宽获得归一化值,例如0.5表示图像中心点
roiBox.fCenterY = (float)(rect.CenterPoint.Y / vmRenderControl1.ImageSource.Height); // 需要使用像素值Y/图像高获得归一化值,例如0.5表示图像中心点
roiBox.fWidth = (float)(rect.Width / vmRenderControl1.ImageSource.Width); // 同上
roiBox.fHeight = (float)(rect.Height / vmRenderControl1.ImageSource.Height); // 同上
roiBox.fAngle = (float)rect.Angle;
Marshal.StructureToPtr(roiBox, ptr + ptrLocation, true);
ptrLocation += Marshal.SizeOf(roiBox);
}
}
VmModule module = (VmModule)VmSolution.Instance[ModuleName];
// 设置感兴趣ROI
ServerSDKManager.serverSDKManager.mModuleManager.SetBinaryData(module.ID, "RoiType", ptr, roiSize);
// 释放内存
Marshal.FreeHGlobal(ptr);
ptr = IntPtr.Zero;
strMsg = "设置多个ROI成功";
}
catch (VmException ex)
{
string strMsg = "ErrorMessage is " + ex.errorMessage + " ErrorCode is " + Convert.ToString(ex.errorCode, 16);
return 0;
}
catch (Exception ex)
{
string strMsg = Convert.ToString(ex);
return 0;
}