From 9b2ad9bafb0739f8ba1e76107011fada5e5883c3 Mon Sep 17 00:00:00 2001
From: C3204 <zhengyabo@lanpucloud.cn>
Date: 星期五, 10 四月 2026 16:23:08 +0800
Subject: [PATCH] 修复LB3D相机参数设置问题以及新增兰宝3D相机参数存储在本地以及初始化给相机参数。

---
 LB_VisionProcesses/Cameras/LBCameras/LBCamera.cs |  267 +++++++++++++++++++++++++++++++---------------------
 1 files changed, 158 insertions(+), 109 deletions(-)

diff --git a/LB_VisionProcesses/Cameras/LBCameras/LBCamera.cs b/LB_VisionProcesses/Cameras/LBCameras/LBCamera.cs
index 810ffd3..123fa04 100644
--- a/LB_VisionProcesses/Cameras/LBCameras/LBCamera.cs
+++ b/LB_VisionProcesses/Cameras/LBCameras/LBCamera.cs
@@ -2,9 +2,13 @@
 using LB_SmartVisionCameraSDK.PHM6000;
 using LB_SmartVisionCommon;
 using LB_VisionProcesses.Cameras;
+using OpenVinoSharp.Extensions.model;
+using SharpCompress.Common;
 using Sunny.UI.Win32;
 using System;
+using System.Collections.Concurrent;
 using System.Collections.Generic;
+using System.ComponentModel;
 using System.Drawing;
 using System.Drawing.Imaging;
 using System.Reflection;
@@ -32,7 +36,6 @@
     {
         private IntPtr _cameraHandle = IntPtr.Zero;
         private PHM6000SensorConfig _sensorConfig;
-        
         // 閲囬泦鍥炶皟
         private AcquisitionCallbackZA _acquisitionCallback;
         private AcquisitionCompletedCallback _acquisitionCompletedCallback;
@@ -418,16 +421,75 @@
 
         public void UpdateSensorConfig(PHM6000SensorConfig config)
         {
-            _sensorConfig = config;
-            if (!_isConnected) return;
-            SetParam(EnumNameId.ExposureTime, (float)config.ExposureTime);
-            SetParam(EnumNameId.AnalogGain, (float)config.AnalogGain);
-            PHM6000Profiler.SetProfilerParameter(_cameraHandle, (int)EnumNameId.ScanLineCount, config.ScanLineCount, 0, 0);
-            PHM6000Profiler.SetProfilerParameter(_cameraHandle, (int)EnumNameId.LineScanTriggerSource, 0, 0, (int)config.LineScanTriggerSource);
-            PHM6000Profiler.SetProfilerParameter(_cameraHandle, (int)EnumNameId.DataAcquisitionTriggerSource, 0, 0, (int)config.DataAcquisitionTriggerSource);
-            if (config.LineScanTriggerSource == EnumLineScanTriggerSource.鍥哄畾棰戠巼)
+            //_sensorConfig = config;
+            //if (!_isConnected) return;
+            //SetParam(EnumNameId.ExposureTime, (float)config.ExposureTime);
+            //SetParam(EnumNameId.AnalogGain, (float)config.AnalogGain);
+            //PHM6000Profiler.SetProfilerParameter(_cameraHandle, (int)EnumNameId.ScanLineCount, config.ScanLineCount, 0, 0);
+            //PHM6000Profiler.SetProfilerParameter(_cameraHandle, (int)EnumNameId.LineScanTriggerSource, 0, 0, (int)config.LineScanTriggerSource);
+            //PHM6000Profiler.SetProfilerParameter(_cameraHandle, (int)EnumNameId.DataAcquisitionTriggerSource, 0, 0, (int)config.DataAcquisitionTriggerSource);
+            //if (config.LineScanTriggerSource == EnumLineScanTriggerSource.鍥哄畾棰戠巼)
+            //{
+            //    PHM6000Profiler.SetProfilerParameter(_cameraHandle, (int)EnumNameId.SoftwareTriggerRate, 0, config.SoftwareTriggerRate, 0);
+            //}
+
+            int result = 0;
+            var type = config.GetType();
+            var propLineScan = type.GetProperty(nameof(config.LineScanTriggerSource));
+            var val = (EnumLineScanTriggerSource)propLineScan.GetValue(config);
+            var props = config.GetType().GetProperties();
+
+            //鎺掗櫎Y杞�
+            props = props.Where(d => d.Name != nameof(PHM6000SensorConfig.YResolution)).ToArray();
+            //鎺掗櫎涓嶉渶瑕佺殑椤�
+            if (val == EnumLineScanTriggerSource.鍥哄畾棰戠巼)
             {
-                PHM6000Profiler.SetProfilerParameter(_cameraHandle, (int)EnumNameId.SoftwareTriggerRate, 0, config.SoftwareTriggerRate, 0);
+                props = props.Where(d => d.Name != nameof(PHM6000SensorConfig.EncoderTriggerDirection) && d.Name != nameof(PHM6000SensorConfig.EncoderTriggerInterval) && d.Name != nameof(PHM6000SensorConfig.EncoderTriggerSignalCountingMode)).ToArray();
+            }
+            else
+            {
+                props = props.Where(d => d.Name != nameof(PHM6000SensorConfig.SoftwareTriggerRate)).ToArray();
+            }
+            foreach (var p in props)
+            {
+                //璺宠繃鑷畾涔夊弬鏁�
+                var iscustomAttr = p.GetCustomAttribute<IsCustomAttribute>();
+                if (iscustomAttr != null) continue;
+                //鍒ゆ柇鏄�6030浼犳劅鍣ㄨ繕鏄櫘閫氫紶鎰熷櫒
+                if (SN.StartsWith("LX030") && p.Name == nameof(config.AnalogGain))
+                {
+                    continue;
+                }
+                if (!SN.StartsWith("LX030") && p.Name == nameof(config.AnalogGainFor6030))
+                {
+                    continue;
+                }
+                var id = Convert.ToInt32(Enum.Parse(typeof(EnumNameId), p.Name));
+                if (p.PropertyType == typeof(int))
+                {
+                    var value = Convert.ToInt32(p.GetValue(config));
+                    result = PHM6000Profiler.SetProfilerParameter(_cameraHandle, id, value, 0, 0);
+                }
+                else if (p.PropertyType == typeof(float))
+                {
+                    var value = Convert.ToDouble(p.GetValue(config));
+                    result = PHM6000Profiler.SetProfilerParameter(_cameraHandle, id, 0, value, 0);
+                }
+                else
+                {
+                    var value = Convert.ToInt32(p.GetValue(config));
+                    result = PHM6000Profiler.SetProfilerParameter(_cameraHandle, id, 0, 0, value);
+                }
+                if (result == -1)
+                {
+                    var disattr = p.GetCustomAttribute<DisplayNameAttribute>();
+                    var name = disattr?.DisplayName ?? p.Name;
+                    throw new Exception($"璁剧疆鍙傛暟{name}鏃朵笉鎴愬姛锛�");
+                }
+            }
+            var finalResult = PHM6000Profiler.SaveAllParametersToDevice(_cameraHandle);
+            if (finalResult != 0)
+            {
             }
             PHM6000Profiler.SaveAllParametersToDevice(_cameraHandle);
         }
@@ -533,14 +595,23 @@
 
         private void CreateAndFireBitmap()
         {
+            Bitmap bmp = null;
+            BitmapData bmpData = null;
+
             try
             {
                 int width = _currentBitmapWidth;
-                int height = _currentLineCount; // 浣跨敤瀹為檯閲囬泦鍒扮殑琛屾暟
+                int height = _currentLineCount;
 
-                if (width <= 0 || height <= 0 || _rawPixelBuffer == null) return;
+                // 鍩虹鍚堟硶鎬ф牎楠�
+                if (width <= 0 || height <= 0 || _rawPixelBuffer == null || _rawPixelBuffer.Length < width * height)
+                {
+                    AsyncLogHelper.Warn($"LBCamera[{SN}]: 鍥惧儚鍙傛暟鏃犳晥锛岃烦杩囩敓鎴�");
+                    return;
+                }
 
-                Bitmap bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
+                // 1. 鍒涘缓8浣嶇伆搴︿綅鍥�
+                bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
 
                 // 璁剧疆鐏板害璋冭壊鏉�
                 ColorPalette palette = bmp.Palette;
@@ -550,9 +621,8 @@
                 }
                 bmp.Palette = palette;
 
-                // 鎷疯礉鏁版嵁
-                BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
-                
+                // 2. 楂樻晥鍐呭瓨鎷疯礉锛堟敮鎸丼tride瀵归綈锛屾暣琛屽鍒讹級
+                bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
                 // 娉ㄦ剰锛欱itmap Stride 鍙兘涓嶇瓑浜� Width锛岄渶瑕侀�愯鎷疯礉
                 int stride = bmpData.Stride;
                 IntPtr ptr = bmpData.Scan0;
@@ -567,141 +637,120 @@
                 }
 
                 bmp.UnlockBits(bmpData);
+                bmpData = null; // 鏍囪宸茶В閿�
 
                 _frameCount++;
-                AsyncLogHelper.Info($"LBCamera[{SN}]: Frame {_frameCount} generated ({width}x{height})");
-                //绌哄�兼牎楠岋細杞崲澶辫触鍒欑洿鎺ヨ繑鍥�
-                if (bmp == null)
+                AsyncLogHelper.Info($"LBCamera[{SN}]: 鐢熸垚绗� {_frameCount} 甯� ({width}x{height})");
+
+                // 3. 鑾峰彇/鍒涘缓绾跨▼瀹夊叏闃熷垪
+                var queue = CollectedImages.GetOrAdd(SN, new ConcurrentQueue<Bitmap>());
+
+                // 4. 闃熷垪闄愭祦锛岄槻姝㈠唴瀛樻孩鍑�
+                if (queue.Count >= MAX_QUEUE_CAPACITY)
                 {
-                    AsyncLogHelper.Warn(SN + "甯ц浆鎹负Bitmap澶辫触锛岃烦杩囧鐞�");
-                    return;
-                }
-                // 绾跨▼瀹夊叏鍦板皢Bitmap娣诲姞鍒癈ollectedImages瀛楀吀
-                lock (_collectedImagesLock)
-                {
-                    // 纭繚褰撳墠鐩告満SN瀵瑰簲鐨勫垪琛ㄥ瓨鍦�
-                    if (!CollectedImages.ContainsKey(SN))
+                    if (queue.TryDequeue(out Bitmap old))
                     {
-                        CollectedImages[SN] = new List<Bitmap>();
+                        old.Dispose(); // 涓㈠純鏈�鏃у抚锛岄噴鏀惧唴瀛�
+                        AsyncLogHelper.Warn($"LBCamera[{SN}]: 闃熷垪宸叉弧锛岃嚜鍔ㄤ涪寮冩渶鏃у抚");
                     }
-                    CollectedImages[SN].Add(bmp);
-                    AsyncLogHelper.Info(SN + $"鍥惧儚宸插姞鍏ョ紦瀛橈紝褰撳墠缂撳瓨鏁伴噺锛歿CollectedImages[SN].Count}");
                 }
 
-                // 澶勭悊CollectedImages涓殑鍥惧儚锛氶亶鍘嗘秷璐瑰垪琛ㄧ涓�涓厓绱犵洿鍒颁负绌�
-                ProcessCollectedImages();
-                //// 寮傛瑙﹀彂浜嬩欢锛岄伩鍏嶉樆濉濻DK鍥炶皟绾跨▼
-                //Task.Factory.StartNew(() => 
+                // 5. 鍏ラ槦
+                queue.Enqueue(bmp);
+                AsyncLogHelper.Info($"LBCamera[{SN}]: 鍥惧儚鍏ラ槦锛屽綋鍓嶉槦鍒楋細{queue.Count}");
+
+                // 6. 鍚姩闃熷垪锛堝崟渚嬶紝閬垮厤澶氱嚎绋嬮噸澶嶏級
+                StartConsumeQueue();
+                //Task.Factory.StartNew(() =>
                 //{
-                //    try
+                //    CallBackImg = (Bitmap)bitmap.Clone();
+                //    if (CallBackImg == null)
                 //    {
-                //        ImageGrabbed?.Invoke(this, new LBCameraEventArgs(SN, bmp, true));
-                //        CallBackImg = (Bitmap)bmp.Clone();
-                //        if (CallBackImg == null)
-                //        {
-                //            return;
-                //        }
-                //        if (GetTriggerMode(out TriggerMode mode, out TriggerSource source))
-                //        {
-                //            if (mode == TriggerMode.On && source != TriggerSource.Software)
-                //                TriggerRunMessageReceived?.Invoke(SN, source.ToString());  // 瑙﹀彂杩愯浜嬩欢
-                //        }
-                //        bmp.Dispose();
+                //        return;
                 //    }
-                //    catch (Exception ex)
+                //    if (GetTriggerMode(out TriggerMode mode, out TriggerSource source))
                 //    {
-                //        AsyncLogHelper.Error($"LBCamera: Event Invoke error - {ex.Message}");
-                //        bmp.Dispose(); // 寮傚父鏃堕噴鏀捐祫婧�
+                //        if (mode == TriggerMode.On && source != TriggerSource.Software)
+                //            TriggerRunMessageReceived?.Invoke(SN, source.ToString());  // 瑙﹀彂杩愯浜嬩欢
                 //    }
+                //    bitmap.Dispose();
                 //});
             }
             catch (Exception ex)
             {
-                AsyncLogHelper.Error($"LBCamera: CreateBitmap error - {ex.Message}");
+                AsyncLogHelper.Error($"LBCamera[{SN}]: 鍒涘缓鍥惧儚澶辫触 - {ex.Message}", ex);
+            }
+            finally
+            {
+                // 寮哄埗璧勬簮閲婃斁锛岀粷瀵规潨缁濇硠婕�
+                if (bmpData != null)
+                {
+                    try { bmp?.UnlockBits(bmpData); } catch { }
+                }
+                // 娉ㄦ剰锛歜mp 宸插叆闃燂紝涓嶈兘鍦ㄨ繖閲岄噴鏀撅紝鐢辫皟鐢ㄨ�呴噴鏀�
             }
         }
+
+        /// <summary>
+        /// 鍚姩闃熷垪锛堜繚璇佸崟绾跨▼锛�
+        /// </summary>
+        private void StartConsumeQueue()
+        {
+            // 浣跨敤杞婚噺绾у垽鏂紝閬垮厤閲嶅鍚姩娑堣垂浠诲姟
+            if (CollectedImages.TryGetValue(SN, out var queue) && !queue.IsEmpty)
+            {
+                Task.Factory.StartNew(ProcessImageQueue, TaskCreationOptions.LongRunning);
+            }
+        }
+
         /// <summary>
         /// 澶勭悊CollectedImages涓殑缂撳瓨鍥惧儚
         /// 鏍稿績閫昏緫锛氶亶鍘嗗彇绗竴涓浘鍍� -> 璧嬪�肩粰CallBackImg -> 瑙﹀彂浜嬩欢 -> 閲婃斁骞剁Щ闄�
         /// </summary>
-        private void ProcessCollectedImages()
+        private void ProcessImageQueue()
         {
-            Task.Factory.StartNew(() =>
+            try
             {
-                // 鍔犻攣淇濊瘉绾跨▼瀹夊叏锛岄槻姝㈠绾跨▼鍚屾椂鎿嶄綔鍒楄〃
-                lock (_collectedImagesLock)
+                if (!CollectedImages.TryGetValue(SN, out var queue) || queue.IsEmpty)
+                    return;
+
+                // 鐭攣锛氫粎鍑洪槦锛屼笉闃诲鐢熶骇
+                while (queue.TryDequeue(out Bitmap bitmap))
                 {
-                    // 鏍¢獙褰撳墠鐩告満鐨勫浘鍍忓垪琛ㄦ槸鍚﹀瓨鍦ㄤ笖鏈夋暟鎹�
-                    if (!CollectedImages.ContainsKey(SN) || CollectedImages[SN].Count == 0)
-                    {
-                        AsyncLogHelper.Info(SN + "褰撳墠鏃犵紦瀛樺浘鍍忥紝璺宠繃澶勭悊");
-                        return;
-                    }
-                    // 寰幆澶勭悊锛氱洿鍒板垪琛ㄤ负绌�
-                    while (CollectedImages[SN].Count > 0)
+                    using (bitmap) // 鑷姩閲婃斁锛歶sing 鏄渶瀹夊叏鐨勬柟寮�
                     {
                         try
                         {
-                            // 1 鍙栧垪琛ㄧ涓�涓储寮曠殑鍥惧儚璧嬪�肩粰CallBackImg
-                            Bitmap firstBitmap = CollectedImages[SN][0];
-                            ImageGrabbed?.Invoke(this, new LBCameraEventArgs(SN, firstBitmap, true));
-                            CallBackImg = (Bitmap)firstBitmap.Clone(); // 鍏嬮殕閬垮厤鍘熷璞¤閲婃斁鍚庡紩鐢ㄥけ鏁�
+                            // 鍏抽敭锛氫簨浠朵紶閫掑厠闅嗗璞★紝缁濆瀹夊叏锛屼笉浼犻�掑師璧勬簮
+                            using (Bitmap clone = (Bitmap)bitmap.Clone())
+                            {
+                                // 瑙﹀彂鍥惧儚浜嬩欢
+                                ImageGrabbed?.Invoke(this, new LBCameraEventArgs(SN, clone, true));
+                                CallBackImg = (Bitmap)clone.Clone();
+                            }
 
-                            // 2 鑾峰彇瑙﹀彂妯″紡骞跺垽鏂槸鍚﹁Е鍙戣繍琛屼簨浠�
+                            // 瑙﹀彂妯″紡鍒ゆ柇
                             if (GetTriggerMode(out TriggerMode mode, out TriggerSource source))
                             {
-                                // 纭Е鍙戞ā寮忎笅瑙﹀彂杩愯浜嬩欢
                                 if (mode == TriggerMode.On && source != TriggerSource.Software)
                                 {
-                                    AsyncLogHelper.Info(SN + $"瑙﹀彂纭Е鍙戜簨浠讹紝瑙﹀彂婧愶細{source}");
                                     TriggerRunMessageReceived?.Invoke(SN, source.ToString());
+                                    AsyncLogHelper.Info($"LBCamera[{SN}]: 纭Е鍙戜簨浠� - {source}");
                                 }
                             }
-                            else
-                            {
-                                AsyncLogHelper.Warn(SN + "鑾峰彇瑙﹀彂妯″紡澶辫触锛岃烦杩囦簨浠惰Е鍙�");
-                            }
-
-                            // 3 閲婃斁绗竴涓浘鍍忚祫婧愬苟浠庡垪琛ㄧЩ闄�
-                            // 鍏堥噴鏀綛itmap鍐呭瓨锛屽啀绉婚櫎鍒楄〃鍏冪礌
-                            firstBitmap.Dispose();
-                            CollectedImages[SN].RemoveAt(0);
-                            AsyncLogHelper.Info(SN + $"宸叉秷璐圭紦瀛樺浘鍍忥紝鍓╀綑缂撳瓨鏁伴噺锛歿CollectedImages[SN].Count}");
                         }
                         catch (Exception ex)
                         {
-                            AsyncLogHelper.Error(SN + $"澶勭悊缂撳瓨鍥惧儚寮傚父锛歿ex.Message}", ex);
-                            // 鍗曚釜鍥惧儚澶勭悊澶辫触鏃讹紝绉婚櫎璇ュ浘鍍忛伩鍏嶉樆濉炲悗缁鐞�
-                            if (CollectedImages[SN].Count > 0)
-                            {
-                                try
-                                {
-                                    CollectedImages[SN][0]?.Dispose(); // 灏濊瘯閲婃斁
-                                    CollectedImages[SN].RemoveAt(0);
-                                }
-                                catch (Exception innerEx)
-                                {
-                                    AsyncLogHelper.Error(SN + $"娓呯悊寮傚父鍥惧儚澶辫触锛歿innerEx.Message}", innerEx);
-                                }
-                            }
-                            // 鍗曚釜鍥惧儚澶勭悊澶辫触涓嶇粓姝㈠惊鐜紝缁х画澶勭悊涓嬩竴涓�
-                            // 4. 鎵�鏈夊浘鍍忓鐞嗗畬鎴愬悗锛屾竻绌篊allBackImg
-                            if (CallBackImg != null)
-                            {
-                                CallBackImg.Dispose();
-                                CallBackImg = null;
-                            }
-                            continue;
-                        }
-                        // 4. 鎵�鏈夊浘鍍忓鐞嗗畬鎴愬悗锛屾竻绌篊allBackImg
-                        if (CallBackImg != null)
-                        {
-                            CallBackImg.Dispose();
-                            CallBackImg = null;
+                            AsyncLogHelper.Error($"LBCamera[{SN}]: 澶勭悊鍗曞抚鍥惧儚寮傚父 - {ex.Message}", ex);
+                            continue; // 鍗曞抚寮傚父锛岀户缁鐞嗕笅涓�甯�
                         }
                     }
                 }
-            });
+            }
+            catch (Exception ex)
+            {
+                AsyncLogHelper.Error($"LBCamera[{SN}]: 娑堣垂闃熷垪寮傚父 - {ex.Message}", ex);
+            }
         }
 
 

--
Gitblit v1.9.3