349体积相机获取测量时间点和位置信息
简介:一种使用349体积相机获取体积测量开始时间点和结束测量时间点以及包裹四个顶角位置信息的可行办法。
- 本文档适用的问题
- 体积相机型号为:MV-DL2040-04B-H、MV-DL2025-04D-H、MV-DL2025-04H-H
- 项目中存在需要获取测量物体 体积测量的开始时间和结束时间点的需求
- 项目中存在需要获取测量物体的四个顶点的坐标的需求;
- 部分定义
- 包裹测量起始帧号:检测到包裹头部的图像帧
- 包裹测量结束帧号:检测到包裹尾部的图像帧
- 包裹开始测量时间:对应包裹测量起始帧生成的时间
- 包裹结束测量时间:对应包裹测量结束帧生成的时间
- 包裹四个顶点坐标基于的坐标系:
点云坐标系,坐标系遵从右手准则,Y轴朝向传送带运动方向;
坐标原点:
采用标准箱标定时,坐标原点和光平面标定参数有关系,原点不固定。(获取坐标信息不推荐使用该种方式进行系统标定)
采用标定板标定时,坐标原点为系统标定时标定板棋盘格左上角(移动前)。
- 本文档参考环境说明
操作系统:Windows7
网卡:Intel(R) Ethernet Connection (2) I219-LM
相机型号:MV-DL2040-04B-H
客户端:3DMVS2.0.1 build20200911
体积SDK:VolumeMeasureSDK_V2.2.0.1_20200908(基于3DMVS客户端)
注:确保网络环境已配置、相机已经标定。
网络环境配置请参考网口丢包指导文档;
相机标定请参考相关标定指导资料。
- 操作步骤
- 相机参数检查确认
使用3DMVS连接相机,确保相机已经标定且可以正常测量体积。
- 点云图模式下,点云正常,未出现严重倾斜;
- ROI和过滤区域已经绘制;
- 相机在点云模式下,“实际帧速率(fps)”可以稳定达到“采集帧率控制”阈值,图像输出稳定不丢包;
- 测量及校准模块下,测量类型使用“相机直出体积”和“积分体积”均可以正常出体积。
- 不满足以上条件请根据情况进行排除异常情况,或联系相关技术人员提供技术保障。
- 获取测量物体的四个顶点的坐标
- 使用3DMVS软件安装路径下的体积Demo测试,默认路径为C:\Program Files (x86)\3DMVS\Development\MvVolMeasureSDK\Samples
Documentations:体积SDK开发手册文件夹,包含部分体积相机使用指导手册;
Runtime:体积运行时库文件夹,3DMVS安装时静默安装,已安装3DMVS的PC不需要再次安装,未安装3DMVS的PC需要根据说明进行安装;
Samples:Demo存放文件夹,包含C#和VC的主动与回调获取体积示例;
SDK:文件夹包含DotNet库,lib库与头文件;
注:更为详细的说明请查看开发手册,这里不再赘述
这里以C#回调方式获取体积Demo为例,打开项目,在回调函数ProcessCallBackResult里添加如下代码:
listBox1.Items.Add("有体积信息时的图像标记位:"+stResultInfo.nImgFlag);
listBox1.Items.Add("位置信息XYZ:");
for (int i = 0; i < stResultInfo.stVolumeInfo.vertex_pnts.Count(); i++)
{
listBox1.Items.Add("位置信息[" + i + "]:(" + stResultInfo.stVolumeInfo.vertex_pnts[i].fX + ","
+ stResultInfo.stVolumeInfo.vertex_pnts[i].fY + ","
+ stResultInfo.stVolumeInfo.vertex_pnts[i].fZ + ")");
}
注:代码仅供测试参考,请根据实际情况进行调整
- 执行程序进行测试,由于该版本SDK采用运行库,所以不需要以往的拷贝dll,拷贝measure文件步骤;
- 查找设备、连接相机,工作模式选择1、5、9均可
- 点击开始工作,过包裹测试结果如下:
- 获取测量物体 体积测量的开始时间和结束时间点
- 由于接下来需要使用体积相机输出的图像信息,我们在创建句柄(CreateHandleBySerial)之后,继续添加代码:
//设置开启图像输出使能
nRet = m_csVolMeasure.SetVolAPIOutputImgEnable(true);
if (ERROR_DEFINE.MV_VOLM_OK != (ERROR_DEFINE)nRet)
{
string strErr = string.Format("SetVolAPIOutputImgEnable falied! nRet = {0} nRet = 0x{1:x}", nRet, nRet);
MessageBox.Show(strErr);
}
- 继续在回调函数ProcessCallBackResult里添加如下代码:
//检测图像标记位
if (bProcess && (1 == stResultInfo.nImgFlag))
{
//用户自定义,处理图像信息,图像位于结构体stResultInfo.stImage
textBox1.Text = ConvertLongDateTime(stResultInfo.stImage.nHostTimeStamp).ToString();
textBox2.Text = stResultInfo.stImage.nFrameNum.ToString();//帧号最大值
}
//有体积并根据图像信息的时间戳计算开始测量时间和结束测量时间
if (bProcess&&(1 == stResultInfo.nVolumeFlag) && (1 == stResultInfo.nImgFlag))
{
listBox1.Items.Add("输出体积时间:"+ConvertLongDateTime(stResultInfo.stImage.nHostTimeStamp).ToString());
listBox1.Items.Add("输出体积帧号:" + stResultInfo.stImage.nFrameNum.ToString());
listBox1.Items.Add("测量开始帧号:" + stResultInfo.stVolumeInfo.start_frm_id);
listBox1.Items.Add("测量结束帧号:" + stResultInfo.stVolumeInfo.end_frm_id);
}
- 需要用到以下方法,将“主机生成时间”nHostTimeStamp的long类型转换为DateTime:
public static DateTime ConvertLongDateTime(long d)
{
//Long格式:标准时间从1970年到现在的毫秒数
DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
long lTime = long.Parse(d + "0000");
TimeSpan toNow = new TimeSpan(lTime);
DateTime dtResult = dtStart.Add(toNow);
return dtResult;
}
- 执行程序进行测试,查找相机、连接相机,工作模式推荐选择1、5;
特别说明:这里测量模式选择9相机直出体积时,会出现体积数据和图像数据不会一起输出的情况,也就是不满足
“(1 == stResultInfo.nVolumeFlag) && (1 == stResultInfo.nImgFlag)
的判断”
- 如何计算测量开始时间和测量结束时间:
测量开始时间=体积信息输出的时间-(体积信息输出帧号-测量开始帧号)*1s300Fps(帧率阈值)
测量结束时间=体积信息输出的时间-(体积信息输出帧号-测量结束帧号)*1s300Fps(帧率阈值)
注:这里帧号差计算时,需要考虑帧号最大值为65535,跳转0