- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
1、简介 1、说明一下 最近,我在开发一个玻璃幕墙检测的项目,这个项目需要使用到海康的相机系统。业务是这样的,相机按着指定的坐标,扫描玻璃幕墙的每块玻璃,通过算法查看是否有损坏的,如果有就发出报警信息,告诉客户。这个项目是有一个同事写好的,我后来重构了一下,但是运行起来,运行若干次,就退悄无声息的退出软件,什么也不提示。通过这个现象,我知道肯定是和硬件交互的时候出了问题,而且抛出任何异常。海康的日志文件也没有显示是什么有价值的东西。 但是,通过努力的查找,调试,排除,终于找到了问题的关键,我们有四个相机,就有四个回调函数,用于处理图像,但是每个相机注册了一个自己的回调,应该是四个相机,设置四个回调,但是回调函数的实例是一个,否则就会出现程序毫无征兆的崩溃。 2、开发平台 开发工具:Visual Studio2022 开发语言:C# 开发平台:Winform 7.0 海康类库:MvCamCtrl.NET 2、详细步骤 这个问题搞了我两天才搞定,但是搞定了,心里舒服了。今天就把思路写下来,自己可以查找,也可以帮助大家。 知道问题的关键点了,解决也就方便了。这也叫难着不会,会的不难.
1、一定要把 MyCamera.cbOutputExdelegate 声明为类的成员。 private MyCamera.cbOutputExdelegate _outputImageDelegate,
1 #region 私有实例字段 2 3 private MyCamera[]? _myCameras; // 相机实例的数组。 4 private MyCamera.MV_CC_DEVICE_INFO_LIST _deviceInformationList; // 相机信息的列表 5 7 // 图片文件的存储路径:根目录/当前扫描时间(作为目录)/相机编号 8 private string ? _saveImageBaseDirectory; // 图像文件存储的根路径路径。 9 private string ? _saveImageOnceTimeDirectory; // 单次扫描图像文件的存储路径,目录结构:根目录+当前扫描时间 10 private string []? _saveImageForCameraDirectory; // 最终存储图片文件的路径,目录结构:根目录+当前扫描时间+相机序列号(有多少台相机,就有多少个目录) 11 private IntPtr[]? _imageDisplayHandles; // 针对每台相机图像进行显示处理,应为有多台,所以是数据类型是数组。 14 private MyCamera.cbOutputExdelegate _outputImageDelegate ; 17 #endregion
2、一定要在构造函数里初始化,当然,如果你可以保证一个实例,就可以放在其他地方,我是为了方便,没有过多的设计。 _outputImageDelegate = new MyCamera.cbOutputExdelegate(SaveImageCallBack),
1 /// <summary> 2 /// 初始化新实例。 3 /// </summary> 4 public frmMonitoring() 5 { 6 InitializeComponent(); 7 _outputImageDelegate = new MyCamera.cbOutputExdelegate(SaveImageCallBack); 8 _patrolProcessor = new OrientalMotorPatrolProcessor(); 9 10 11 #region 全局异常处理 12 13 AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; 14 Application.ThreadException += Application_ThreadException; 15 16 #endregion 17 }
这是附送的方法,异常处理.
1 #region 异常处理 2 3 /// <summary> 4 /// 该方法处理用于处理 Windows 窗体线程引发的异常。 5 /// </summary> 6 /// <param name="sender"></param> 7 /// <param name="e"></param> 8 /// <exception cref="NotImplementedException"></exception> 9 private void Application_ThreadException( object sender, ThreadExceptionEventArgs e) 10 { 11 try 12 { 13 ShowPromptMessage(e.Exception.Message); 14 } 15 catch (Exception) 16 { 17 try 18 { 19 ShowPromptMessage( " 不可恢复的非 Windows 窗体线程异常,应用程序将退出! " ); 20 } 21 finally 22 { 23 Application.Exit(); 24 } 25 } 26 } 27 28 /// <summary> 29 /// 使用该方法处理非UI线程所发生的异常。 30 /// </summary> 31 /// <param name="sender"></param> 32 /// <param name="e"></param> 33 /// <exception cref="NotImplementedException"></exception> 34 private void CurrentDomain_UnhandledException( object sender, UnhandledExceptionEventArgs e) 35 { 36 try 37 { 38 var exceptionObject = e.ExceptionObject as Exception; 39 if (exceptionObject != null ) 40 { 41 ShowPromptMessage(exceptionObject.Message); 42 } 43 } 44 catch (Exception) 45 { 46 try 47 { 48 ShowPromptMessage( " 不可恢复的非 Windows 窗体线程异常,应用程序将退出! " ); 49 } 50 finally 51 { 52 Application.Exit(); 53 } 54 } 55 56 } 57 58 #endregion
辅助方法。 。
1 /// <summary> 2 /// 用于显示系统的提示信息,包括异常信息、操作信息等。 3 /// </summary> 4 /// <param name="message"> 需要显示的信息内容。 </param> 5 /// <param name="stateCode"> 具体操作的状态码值,该值可有可无,不是所有操作都有状态值的,默认值:0,表示没有状态值。 </param> 6 private void ShowPromptMessage( string message, int stateCode = 0 ) 7 { 8 string resultMessage; 9 if (stateCode == 0 ) 10 { 11 resultMessage = $ " {message}\r\n " ; 12 } 13 else 14 { 15 resultMessage = $ " {message}: Error ={string.Format( " { 0 :X} " , stateCode)} " ; 16 } 17 18 switch (stateCode) 19 { 20 case MyCamera.MV_E_HANDLE: resultMessage += " ,错误或无效句柄(Error or invalid handle)\r\n " ; break ; 21 case MyCamera.MV_E_SUPPORT: resultMessage += " ,不支持的功能(Not supported function)\r\n " ; break ; 22 case MyCamera.MV_E_BUFOVER: resultMessage += " ,缓存已满(Cache is full)\r\n " ; break ; 23 case MyCamera.MV_E_CALLORDER: resultMessage += " ,函数调用顺序错误(Function calling order error)\r\n " ; break ; 24 case MyCamera.MV_E_PARAMETER: resultMessage += " ,不正确的参数(Incorrect parameter)\r\n " ; break ; 25 case MyCamera.MV_E_RESOURCE: resultMessage += " ,应用资源失败(Applying resource failed)\r\n " ; break ; 26 case MyCamera.MV_E_NODATA: resultMessage += " ,没有数据(No data )\r\n " ; break ; 27 case MyCamera.MV_E_PRECONDITION: resultMessage += " ,前提条件错误,或运行环境已更改(Precondition error, or running environment changed)\r\n " ; break ; 28 case MyCamera.MV_E_VERSION: resultMessage += " ,版本不匹配(Version mismatches)\r\n " ; break ; 29 case MyCamera.MV_E_NOENOUGH_BUF: resultMessage += " ,内存不足(Insufficient memory)\r\n " ; break ; 30 case MyCamera.MV_E_UNKNOW: resultMessage += " ,未知错误(Unknown error)\r\n " ; break ; 31 case MyCamera.MV_E_GC_GENERIC: resultMessage += " ,一般错误(General error)\r\n " ; break ; 32 case MyCamera.MV_E_GC_ACCESS: resultMessage += " ,节点访问条件错误(Node accessing condition error)\r\n " ; break ; 33 case MyCamera.MV_E_ACCESS_DENIED: resultMessage += " ,没有权限(No permission)\r\n " ; break ; 34 case MyCamera.MV_E_BUSY: resultMessage += " ,设备正忙或网络断开连接(Device is busy, or network disconnected)\r\n " ; break ; 35 case MyCamera.MV_E_NETER: resultMessage += " ,网络错误(Network error)\r\n " ; break ; 36 } 37 38 SetAsyncControlText(txtExceptionMessage, $ " >> {resultMessage} " , true ); 39 }
3、实例化相机,并初始化回调函数.
1 MyCamera.MV_CC_DEVICE_INFO[] _deviceInfoArray = new MyCamera.MV_CC_DEVICE_INFO[localDeviceCount]; 2 object ? localDeviceInfo = null ; 3 MyCamera.MV_CC_DEVICE_INFO device; 4 5 for ( int i = 0 ; i < localDeviceCount; ++ i) 6 { 7 if (_deviceInformationList.pDeviceInfo != null && _deviceInformationList.pDeviceInfo.Length > 0 ) 8 { 9 localDeviceInfo = Marshal.PtrToStructure(_deviceInformationList.pDeviceInfo[i], typeof (MyCamera.MV_CC_DEVICE_INFO)); 10 if (localDeviceInfo != null ) 11 { 12 // 获取选择的设备信息 13 device = (MyCamera.MV_CC_DEVICE_INFO)localDeviceInfo; 14 15 // 打开设备 16 if (cameras[i] == null ) 17 { 18 cameras[i] = new MyCamera(); 19 } 20 21 stateCode = cameras[i].MV_CC_CreateDevice_NET( ref device); 22 if (MyCamera.MV_OK != stateCode) 23 { 24 return ; 25 } 26 27 stateCode = cameras[i].MV_CC_OpenDevice_NET(); 28 if (MyCamera.MV_OK != stateCode) 29 { 30 return ; 31 } 32 else 33 { 34 _deviceInfoArray[i] = device; 35 // 探测网络最佳包大小(只对GigE相机有效),我们是USB相机 36 if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE) 37 { 38 int nPacketSize = cameras[i].MV_CC_GetOptimalPacketSize_NET(); 39 if (nPacketSize > 0 ) 40 { 41 stateCode = cameras[i].MV_CC_SetIntValue_NET( " GevSCPSPacketSize " , ( uint )nPacketSize); 42 if (stateCode != MyCamera.MV_OK) 43 { 44 ShowPromptMessage( " Warning: Set Packet Size failed {0:x8} " , stateCode); 45 } 46 } 47 else 48 { 49 ShowPromptMessage( " Warning: Get Packet Size failed {0:x8} " , stateCode); 50 } 51 } 52 53 // 1、开启设置触发模式 54 SetCameraTriggerMode(cameras[i]); 55 // 2、设置具体的触发模式为软触发 56 SetCameraTriggerSource(cameras[i]); 57 cameras[i].MV_CC_RegisterImageCallBackEx_NET(_outputImageDelegate, i); 58 } 59 } 60 } 61 }
4、回调方法的实现。 回调的方法可以根据自己的需求编写,这是我的需求,我的具体编写方法,不能照抄.
1 /// <summary> 2 /// 获取帧数据并保存为图像的回调函数。 3 /// </summary> 4 /// <param name="frameData"> 图像的帧数据。 </param> 5 /// <param name="frameInfo"> 图像的帧信息。 </param> 6 /// <param name="cameraIndex"> 相机的索引,因为有多台相机。 </param> 7 private void SaveImageCallBack(IntPtr frameData, ref MyCamera.MV_FRAME_OUT_INFO_EX frameInfo, IntPtr cameraIndex) 8 { 9 int _cameraIndex = ( int )cameraIndex; 10 11 if (_perCameraTotalFrames != null && _perCameraTotalFrames.Length > 0 ) 12 { 13 // 抓取的帧数 14 ++ _perCameraTotalFrames[_cameraIndex]; 15 16 // 第一个相机数据,每台相机处理的数据是一样的,随机选择第一个,作为结果输出。 17 if (_cameraIndex == 0 ) 18 { 19 SetAsyncControlText(lblAcquisitionCountValue, _perCameraTotalFrames[_cameraIndex].ToString()); 20 } 21 } 22 23 // 显示图像 24 // 将相机图像显示到对应的位置 25 if (_imageDisplayHandles != null && _imageDisplayHandles.Length > 0 ) 26 { 27 MyCamera.MV_DISPLAY_FRAME_INFO displayFrameInfo = new MyCamera.MV_DISPLAY_FRAME_INFO(); 28 displayFrameInfo.hWnd = _imageDisplayHandles[_cameraIndex]; 29 displayFrameInfo.pData = frameData; 30 displayFrameInfo.nDataLen = frameInfo.nFrameLen; 31 displayFrameInfo.nWidth = frameInfo.nWidth; 32 displayFrameInfo.nHeight = frameInfo.nHeight; 33 displayFrameInfo.enPixelType = frameInfo.enPixelType; 34 35 if (_myCameras != null && _myCameras.Length > 0 ) 36 { 37 CameraDisplayOneFrame(_myCameras[_cameraIndex], ref displayFrameInfo); 38 } 39 } 40 41 // 判断当前相机是否允许保存图像 42 if (_isPerCameraSaveImage != null && _isPerCameraSaveImage.Length > 0 ) 43 { 44 if (_isPerCameraSaveImage[_cameraIndex] && _saveImageForCameraDirectory != null && _saveImageForCameraDirectory.Length > 0 && _perCameraSerialNumbers != null && _perCameraSerialNumbers.Length > 0 ) 45 { 46 MyCamera.MV_SAVE_IMG_TO_FILE_PARAM stSaveToFileParam = new MyCamera.MV_SAVE_IMG_TO_FILE_PARAM(); 47 48 stSaveToFileParam.enPixelType = frameInfo.enPixelType; 49 stSaveToFileParam.pData = frameData; 50 stSaveToFileParam.nDataLen = frameInfo.nFrameLen; 51 stSaveToFileParam.nWidth = frameInfo.nWidth; 52 stSaveToFileParam.nHeight = frameInfo.nHeight; 53 54 stSaveToFileParam.enImageType = MyCamera.MV_SAVE_IAMGE_TYPE.MV_Image_Bmp; 55 stSaveToFileParam.nQuality = 100 ; 56 // 图像文件名应包含采集时间、对应相机ID号、玻璃编号等信息 57 var saveImageFullPath = $ " {_saveImageForCameraDirectory[_cameraIndex]}\\{DateTime.Now.ToString( " yyyyMMddHHmmss " )}_{_perCameraSerialNumbers[_cameraIndex]}_{_patrolFileGlassNumber}.bmp " ; 58 stSaveToFileParam.pImagePath = saveImageFullPath; 59 60 if (_myCameras != null && _myCameras.Length > 0 ) 61 { 62 _myCameras[_cameraIndex].MV_CC_SaveImageToFile_NET( ref stSaveToFileParam); 63 CameraSaveImageToFile(_myCameras[_cameraIndex], ref stSaveToFileParam); 64 } 65 } 66 } 67 }
3、总结 我已经实验过单相机回调没问题了,所以多相机就直接复制了多个回调,因此相机回调还没传到外面的实例,就已经崩了,肯定就是封装的问题。看了海康的多相机demo,相机有4个实例,回调函数只有一个实例,4个相机注册了四次回调,但都是同一个回调实例。这就是我发生错误的根本原因。 好了,问题解决了,又学了点技术,继续努力,苍天不负努力的人.
最后此篇关于我在使用Winform7.0开发海康相机应用的时候系统悄无声息的退出的文章就讲到这里了,如果你想了解更多关于我在使用Winform7.0开发海康相机应用的时候系统悄无声息的退出的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我在网上搜索但没有找到任何合适的文章解释如何使用 javascript 使用 WCF 服务,尤其是 WebScriptEndpoint。 任何人都可以对此给出任何指导吗? 谢谢 最佳答案 这是一篇关于
我正在编写一个将运行 Linux 命令的 C 程序,例如: cat/etc/passwd | grep 列表 |剪切-c 1-5 我没有任何结果 *这里 parent 等待第一个 child (chi
所以我正在尝试处理文件上传,然后将该文件作为二进制文件存储到数据库中。在我存储它之后,我尝试在给定的 URL 上提供文件。我似乎找不到适合这里的方法。我需要使用数据库,因为我使用 Google 应用引
我正在尝试制作一个宏,将下面的公式添加到单元格中,然后将其拖到整个列中并在 H 列中复制相同的公式 我想在 F 和 H 列中输入公式的数据 Range("F1").formula = "=IF(ISE
问题类似于this one ,但我想使用 OperatorPrecedenceParser 解析带有函数应用程序的表达式在 FParsec . 这是我的 AST: type Expression =
我想通过使用 sequelize 和 node.js 将这个查询更改为代码取决于在哪里 select COUNT(gender) as genderCount from customers where
我正在使用GNU bash,版本5.0.3(1)-发行版(x86_64-pc-linux-gnu),我想知道为什么简单的赋值语句会出现语法错误: #/bin/bash var1=/tmp
这里,为什么我的代码在 IE 中不起作用。我的代码适用于所有浏览器。没有问题。但是当我在 IE 上运行我的项目时,它发现错误。 而且我的 jquery 类和 insertadjacentHTMl 也不
我正在尝试更改标签的innerHTML。我无权访问该表单,因此无法编辑 HTML。标签具有的唯一标识符是“for”属性。 这是输入和标签的结构:
我有一个页面,我可以在其中返回用户帖子,可以使用一些 jquery 代码对这些帖子进行即时评论,在发布新评论后,我在帖子下插入新评论以及删除 按钮。问题是 Delete 按钮在新插入的元素上不起作用,
我有一个大约有 20 列的“管道分隔”文件。我只想使用 sha1sum 散列第一列,它是一个数字,如帐号,并按原样返回其余列。 使用 awk 或 sed 执行此操作的最佳方法是什么? Accounti
我需要将以下内容插入到我的表中...我的用户表有五列 id、用户名、密码、名称、条目。 (我还没有提交任何东西到条目中,我稍后会使用 php 来做)但由于某种原因我不断收到这个错误:#1054 - U
所以我试图有一个输入字段,我可以在其中输入任何字符,但然后将输入的值小写,删除任何非字母数字字符,留下“。”而不是空格。 例如,如果我输入: 地球的 70% 是水,-!*#$^^ & 30% 土地 输
我正在尝试做一些我认为非常简单的事情,但出于某种原因我没有得到想要的结果?我是 javascript 的新手,但对 java 有经验,所以我相信我没有使用某种正确的规则。 这是一个获取输入值、检查选择
我想使用 angularjs 从 mysql 数据库加载数据。 这就是应用程序的工作原理;用户登录,他们的用户名存储在 cookie 中。该用户名显示在主页上 我想获取这个值并通过 angularjs
我正在使用 autoLayout,我想在 UITableViewCell 上放置一个 UIlabel,它应该始终位于单元格的右侧和右侧的中心。 这就是我想要实现的目标 所以在这里你可以看到我正在谈论的
我需要与 MySql 等效的 elasticsearch 查询。我的 sql 查询: SELECT DISTINCT t.product_id AS id FROM tbl_sup_price t
我正在实现代码以使用 JSON。 func setup() { if let flickrURL = NSURL(string: "https://api.flickr.com/
我尝试使用for循环声明变量,然后测试cols和rols是否相同。如果是,它将运行递归函数。但是,我在 javascript 中执行 do 时遇到问题。有人可以帮忙吗? 现在,在比较 col.1 和
我举了一个我正在处理的问题的简短示例。 HTML代码: 1 2 3 CSS 代码: .BB a:hover{ color: #000; } .BB > li:after {
我是一名优秀的程序员,十分优秀!