C3032
2025-12-20 993f7a5e7075b1e66d307e2b300b1f7054895e1f
增强相机界面和图像处理逻辑

在 `CameraForm.cs` 中添加了设置相机品牌的功能。
在 `2DCameraForm.cs` 中处理未找到相机序列号的情况,并优化了相机抓取逻辑以确保在抓取时正确注册事件。
在 `HRCamera.cs` 中改进了图像采集线程的错误处理,确保在失败时释放帧以防止缓存泄露。
已修改3个文件
64 ■■■■ 文件已修改
LB_SmartVision/Forms/Pages/CameraPage/CameraForm.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
LB_VisionProcesses/Cameras/2DCameraForm.cs 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LB_VisionProcesses/Cameras/HRCamera.cs 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LB_SmartVision/Forms/Pages/CameraPage/CameraForm.cs
@@ -43,7 +43,7 @@
            this.Text = camera.SN;
            //设置品牌
            uiComboBoxBrand.Text = camera.Brand.ToString();
            onlinePictureBox = new UserPictureBox(uiGroupBoxImage);
            this.uiGroupBoxImage.Controls.Clear();
LB_VisionProcesses/Cameras/2DCameraForm.cs
@@ -107,6 +107,12 @@
                cmbSN.Text = SN;
                cmbSN.SelectedIndex = Index;
                // 如果没找到索引(可能是新增的),手动触发一次逻辑以更新UI
                if (Index == -1)
                {
                    cmbSN_SelectedIndexChanged(null, null);
                }
                ckbLocalTest.Checked = Convert.ToBoolean(camConfig.Params.Inputs["是否本地取图"].ToString());
                ckbUpParams.Checked = Convert.ToBoolean(camConfig.Params.Inputs["是否每次写入参数"].ToString());
                ckbRegrab.Checked = Convert.ToBoolean(camConfig.Params.Inputs["是否失败重新取图"].ToString());
@@ -195,15 +201,26 @@
                camera = dicCameras[cmbSN.Text];
            //说明相机已经初始化成功
            if (camera != null && camera.isGrabbing)
            if (camera != null)
            {
                camera.ImageGrabbed -= GetImageBllComplete;
                camera.ImageGrabbed += GetImageBllComplete;
                int Index = cmbBrand.FindString(camera.Brand.ToString());
                if (Index >= 0)
                {
                    cmbBrand.Text = camera.Brand.ToString();
                    cmbBrand.SelectedIndex = Index;
                }
                int Index = cmbBrand.FindString(camera.Brand.ToString()); ;
                cmbBrand.Text = camera.Brand.ToString();
                cmbBrand.SelectedIndex = Index;
                this.btnEdit.Enabled = true;
                if (camera.isGrabbing)
                {
                    camera.ImageGrabbed -= GetImageBllComplete;
                    camera.ImageGrabbed += GetImageBllComplete;
                    this.btnEdit.Enabled = true;
                }
                // 如果相机存在于字典中,说明是已连接的设备,允许编辑
                else if (dicCameras != null && dicCameras.ContainsKey(camera.SN))
                {
                    this.btnEdit.Enabled = true;
                }
            }
        }
LB_VisionProcesses/Cameras/HRCamera.cs
@@ -858,29 +858,38 @@
        /// </summary>
        private void GrabThreadProc()
        {
            IMVDefine.IMV_Frame frame = new IMVDefine.IMV_Frame();
            while (_threadRunning)
            {
                IMVDefine.IMV_Frame frame = new IMVDefine.IMV_Frame();
                try
                {
                    // 获取图像帧
                    int result = _camera.IMV_GetFrame(ref frame, 100);
                    int result = _camera.IMV_GetFrame(ref frame, 1000);
                    if (result == IMVDefine.IMV_OK)
                    {
                        // 处理图像帧
                        ProcessFrame(frame);
                    }
                    else if (result != 0x80000001) // 超时错误代码
                    else
                    {
                        // 非超时错误
                        System.Diagnostics.Debug.WriteLine($"获取图像帧失败,错误码:{result}");
                        // 即使获取失败,也尝试释放帧,防止SDK内部缓存泄露
                        // 注意:frame是每次新建的,如果GetFrame没填充,这里释放应该是安全的(视SDK实现而定)
                        var tempFrame = frame;
                        _camera.IMV_ReleaseFrame(ref tempFrame);
                        if ((uint)result != 0x80000001 && result != -119 && result != -102) // 超时错误代码
                        {
                            // 非超时错误
                            System.Diagnostics.Debug.WriteLine($"获取图像帧失败,错误码:{result}");
                            Thread.Sleep(10); // 出错时稍作等待
                        }
                    }
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine($"采集线程异常:{ex.Message}");
                    Thread.Sleep(10);
                }
                Thread.Sleep(1);
@@ -907,15 +916,17 @@
                    // 更新回调图像
                    CallBackImg = bitmap;
                }
                // 释放帧
                var tempFrame = frame;
                _camera.IMV_ReleaseFrame(ref tempFrame);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"处理图像帧失败:{ex.Message}");
            }
            finally
            {
                // 确保无论如何都释放帧,防止缓存占满
                var tempFrame = frame;
                _camera.IMV_ReleaseFrame(ref tempFrame);
            }
        }
        /// <summary>