轮胎外观检测添加思谋语义分割模型检测工具
C3204
9 小时以前 98c0775fe3b61a37d90dd5756287f385a311adf0
LB_VisionProcesses/Cameras/LBCameras/LBCamera.cs
@@ -2,6 +2,8 @@
using LB_SmartVisionCameraSDK.PHM6000;
using LB_SmartVisionCommon;
using LB_VisionProcesses.Cameras;
using OpenCvSharp;
using OpenCvSharp.Extensions;
using OpenVinoSharp.Extensions.model;
using SharpCompress.Common;
using Sunny.UI.Win32;
@@ -151,11 +153,11 @@
                    // 初始化并注册采集回调 (获取数据用)
                    _acquisitionCallback = new AcquisitionCallbackZA(OnAcquisitionCallbackZA);
                    PHM6000Profiler.SetAcquisitionCallbackZA(_cameraHandle, _acquisitionCallback, IntPtr.Zero);
                    PHM6000Profiler.SetAcquisitionCallbackZA(_cameraHandle, _acquisitionCallback, new IntPtr());
                    // 初始化并注册采集完成回调 (状态通知用)
                    _acquisitionCompletedCallback = new AcquisitionCompletedCallback(OnAcquisitionCompleted);
                    PHM6000Profiler.RegisterAcquisitionCompletedCallback(_cameraHandle, _acquisitionCompletedCallback, IntPtr.Zero);
                    _acquisitionCompletedCallback += OnAcquisitionCompleted;
                    PHM6000Profiler.RegisterAcquisitionCompletedCallback(_cameraHandle, _acquisitionCompletedCallback, new IntPtr());
                    // 强制应用当前配置(确保触发模式等参数正确,避免相机处于未知状态)
                    UpdateSensorConfig(_sensorConfig);
@@ -360,7 +362,7 @@
            config = new CameraConfig(null);
            //UpdateSensorConfig(config);
        }
        public override bool GetImage(out Bitmap bitmap, int outtime = 14500)
        public override bool GetImage(out Bitmap bitmap, int outtime = 14500)
        {
            bitmap = null;
            try
@@ -586,6 +588,8 @@
                }
            }
        }
        private Bitmap bitmap1;
        private int nWidth = 0, nHeight = 0;
        private void OnAcquisitionCompleted(IntPtr pInstance, int nOption)
        {
@@ -627,7 +631,84 @@
            }
            else if (nOption == 2)
            {
                AsyncLogHelper.Info($"LBCamera[{SN}]: Processing End...");
                IntPtr INTPTRImage = PHM6000Profiler.GetIntensityData(_cameraHandle, ref nWidth, ref nHeight);
                bitmap1 = IntensityPtrToMatCloned(INTPTRImage, nWidth, nHeight);
            }
        }
        public Bitmap ConvertIntensityToBitmap(IntPtr dataPtr, int width, int height)
        {
            if (dataPtr == IntPtr.Zero || width <= 0 || height <= 0)
                throw new InvalidOperationException("获取强度数据失败或尺寸无效。");
            // 创建 8bpp 索引位图
            Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
            // 设置灰度调色板(必须,否则显示异常)
            ColorPalette palette = bitmap.Palette;
            for (int i = 0; i < 256; i++)
            {
                palette.Entries[i] = Color.FromArgb(i, i, i);
            }
            bitmap.Palette = palette;
            // 锁定位图数据
            BitmapData bmpData = bitmap.LockBits(
                new Rectangle(0, 0, width, height),
                ImageLockMode.WriteOnly,
                PixelFormat.Format8bppIndexed);
            try
            {
                int srcStride = width;                     // 源数据每行字节数(无填充)
                int dstStride = bmpData.Stride;             // 位图每行字节数(可能对齐)
                int copyBytesPerRow = Math.Min(srcStride, dstStride);
                IntPtr srcRowPtr = dataPtr;
                IntPtr dstRowPtr = bmpData.Scan0;
                // 逐行复制,处理可能的步幅差异
                for (int y = 0; y < height; y++)
                {
                    // 使用 Buffer.MemoryCopy 或 Marshal.Copy 按行复制
                    unsafe
                    {
                        Buffer.MemoryCopy(
                            srcRowPtr.ToPointer(),
                            dstRowPtr.ToPointer(),
                            dstStride,          // 目标缓冲区剩余大小(至少一行)
                            copyBytesPerRow);    // 实际复制字节数
                    }
                    // 移动到下一行
                    srcRowPtr = IntPtr.Add(srcRowPtr, srcStride);
                    dstRowPtr = IntPtr.Add(dstRowPtr, dstStride);
                }
            }
            finally
            {
                bitmap.UnlockBits(bmpData);
            }
            return bitmap;
        }
        public static Bitmap IntensityPtrToMatCloned(IntPtr dataPtr, int width, int height)
        {
            if (dataPtr == IntPtr.Zero || width <= 0 || height <= 0)
            {
                throw new Exception("Failed to get intensity data.");
            }
            // 先创建引用外部数据的 Mat
            using (Mat temp = Mat.FromPixelData(height, width, MatType.CV_8UC1, dataPtr, width))
            {
                // 克隆一份独立内存的 Mat
                return temp.ToBitmap();
            }
        }
@@ -677,8 +758,10 @@
                bmp.UnlockBits(bmpData);
                bmpData = null; // 标记已解锁
                _frameCount++;
                AsyncLogHelper.Info($"LBCamera[{SN}]: 生成第 {_frameCount} 帧 ({width}x{height})");
                AsyncLogHelper.Info($"LBCamera[{SN}]: 生成第 {_frameCount} 帧 ({nWidth}x{nHeight})");
                // 3. 获取/创建线程安全队列
                var queue = CollectedImages.GetOrAdd(SN, new ConcurrentQueue<Bitmap>());
@@ -723,9 +806,9 @@
                // 强制资源释放,绝对杜绝泄漏
                if (bmpData != null)
                {
                    try { bmp?.UnlockBits(bmpData); } catch { }
                    try { bitmap1?.UnlockBits(bmpData); } catch { }
                }
                // 注意:bmp 已入队,不能在这里释放,由调用者释放
                //注意:bmp 已入队,不能在这里释放,由调用者释放
            }
        }
@@ -812,12 +895,16 @@
                    if (Enum.TryParse(typeof(EnumNameId), p.Name, out object nameIdObj))
                    {
                        EnumNameId nameId = (EnumNameId)nameIdObj;
                        //EnumNameId nameId = (EnumNameId)nameIdObj;
                        var nameId = Enum.Parse(typeof(EnumNameId), p.Name);
                        int intValue = 0;
                        double doubleValue = 0;
                        int enumValue = 0;
                        var id = Convert.ToInt32(nameId);
                        var rst = PHM6000Profiler.GetProfilerParameter(_cameraHandle, id, ref intValue, ref doubleValue, ref enumValue);
                        if (PHM6000Profiler.GetProfilerParameter(_cameraHandle, (int)nameId, ref intValue, ref doubleValue, ref enumValue) == 0)
                        if (rst == 0)
                        {
                            if (p.PropertyType == typeof(int))
                            {
@@ -833,7 +920,14 @@
                            }
                            else // Enum or other types
                            {
                                p.SetValue(_sensorConfig, enumValue);
                                if (p.Name.Equals("ROI"))
                                {
                                }
                                else
                                {
                                    p.SetValue(_sensorConfig, enumValue);
                                }
                            }
                        }
                    }