DetectionBl.cs 8.28 KB
using OpenCvSharp;
using OS.Spin.Common;
using OS.Spin.Common.Files;
using OS.Spin.Common.MultiThread;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using static OS.Spin.Modle.Sdk.StructInfos;

namespace OS.Spin.BusinessLayer.SubBusiness
{
    public class DetectionBl
    {
        private int _cameraId = 0;

        private Thread _runThread;
        private SemaphorePool _semaphorePool = SemaphorePool.GetInstance();

        private string _cId = string.Empty;

        private Modle.Sdk.StructInfos.DATA_IMAGE1 _info;

        public delegate Mat GetThreeChannelsMat(int cameraId);

        public GetThreeChannelsMat DoGetThreeChannelMat;

        private const int RS_FACTOR = 4;
        private const int ROI_WIDTH = 500;
        private const int ROI_HEIGHT = 250;
        private const int IMG_WIDTH = 1920;
        private const int IMG_HEIGHT = 1080;

        private IntPtr _initHandle = new IntPtr(0);

        //twb20210902
        private DETC_PARAM detcPara;

        public DetectionBl(string classId, int cameraId)
        {
            try
            {
                _cId = classId;
                _cameraId = cameraId;
                int newCaID = cameraId;
                #region twb20210902
                detcPara = new DETC_PARAM()
                {
                    m_id = newCaID,              //相机ID
                    cloths_kind = OS.Spin.Running.Cache.GetInstance().Cloths_kind,//布种 0:正常布种; 1:薄布 2:厚布
                    index_shift = ConfigHelper.GetInstance().GetConfig().Index_shift,//切边偏移
                    overlap_left = 0,//左相机重叠宽度
                    overlap_right = 0,//右相机重叠宽度
                    width_MidTrue = 0,//中间相机实际宽度
                    width_factorL = 0,//CameraLeft幅宽计算系数
                    width_factorR = 0, //CameraRight幅宽计算系数
                    thresh_ratio = ConfigHelper.GetInstance().GetConfig().Thresh_ratio, //二值化系数
                    num_ratio = ConfigHelper.GetInstance().GetConfig().Num_ratio     //二值化系数2
                };
                int a = OS.Spin.SdkLayer.SdkMyCode.Flaw_DetecInit(ref _initHandle, detcPara);
                #endregion

                _semaphorePool.MakeSemaphore(string.Format("{0}{1}_{2}", OS.Spin.Running.Infos.Names.S_CAMERA_OK, _cId, _cameraId));

                if (null == _runThread)
                {
                    _runThread = new Thread(Run);
                    _runThread.Priority = ThreadPriority.Highest;
                    _runThread.IsBackground = true;
                    _runThread.Start();
                }
            }
            catch (Exception ex)
            {
                LogisTrac.WriteLog(string.Format("DetectionBl:{0}", ex.Message));
            }
        }

        public Modle.Sdk.StructInfos.DATA_IMAGE1 GetGrayImgData()
        {
            return _info;
        }

        public void StartDetection(Modle.Sdk.StructInfos.DATA_IMAGE1 info)
        {
            _info = info;
            OS.Spin.Running.Cache.GetInstance().CamerasOk = true;
            var t = 0;

            //while (t < 5 && OS.Spin.Running.Cache.GetInstance().CamerasOk)
            //{
            //    Thread.Sleep(10);
            //    t++;
            //}

            //if (OS.Spin.Running.Cache.GetInstance().CamerasOk)
            {
                while (!_semaphorePool.Release(string.Format("{0}{1}_{2}", OS.Spin.Running.Infos.Names.S_CAMERA_OK, _cId, _cameraId)))
                {
                    Thread.Sleep(10);
                }
            }
        }
        private object _olock = new object();

        private void Run()
        {
            //  :m_id(0), index_shift(7), edge_width(10), mean_factor(2.3) 

            var id = OS.Spin.Common.Machine.CpuTool.SetCpuID(_cameraId == 2 ? _cameraId + 1 : _cameraId);
            //将当前线程绑定到指定的cpu核心上
            OS.Spin.Common.Machine.CpuTool.SetThreadAffinityMask(OS.Spin.Common.Machine.CpuTool.GetCurrentThread(), new UIntPtr(id));

            while (true)
            {
                _semaphorePool.Wait(string.Format("{0}{1}_{2}", OS.Spin.Running.Infos.Names.S_CAMERA_OK, _cId, _cameraId));
                //if (!OS.Spin.Running.Cache.GetInstance().AutoFlaw)
                //{
                //    while (!_semaphorePool.Release(string.Format("{0}{1}", OS.Spin.Running.Infos.Names.S_DETECTION_OK, _cId)))
                //    {
                //        Thread.Sleep(10);
                //    }
                //    continue;
                //}
                LogisTrac.WriteInfoLog(String.Format("[检测] 开始 ={0}======", _cameraId));
                //var pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Modle.Sdk.StructInfos.Fore_Result)) * 10);
                var pt1 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Modle.Sdk.StructInfos.Fore_Result)) * 50);
                //var ptrs = Marshal.AllocHGlobal(_info.height * _info.width * 3);
                try
                {
                    List<Modle.Sdk.StructInfos.Fore_Result> results = new List<Modle.Sdk.StructInfos.Fore_Result>();
                    var cache = OS.Spin.Running.Cache.GetInstance();
                    int count = 0;

                    if (_info.height * _info.width != 0)
                    {
                        //int realw = 0;
                        #region twb20210902
                        int ret = OS.Spin.SdkLayer.SdkMyCode.Flaw_Detection(_initHandle, detcPara, _info.data, _info.channel, IntPtr.Zero, _info.data, pt1, ref count);
                        if (Convert.ToInt32(OS.Spin.Running.Cache.GetInstance().CMeter) == 15 && OS.Spin.Running.Cache.GetInstance().GetCount < 3)
                        {
                            int clothWidth = 0;
                            int res = OS.Spin.SdkLayer.SdkMyCode.Flaw_ClothsWidth(_initHandle, ref clothWidth);
                            if (res == 0)
                            {
                                OS.Spin.Running.Cache.GetInstance().ClothWidth += clothWidth;
                                OS.Spin.Running.Cache.GetInstance().GetCount++;
                            }
                        }
                        #endregion
                        //cache.GateInfo.SetGateWidthById(_cameraId, realw);
                    }

                    var threeMat = DoGetThreeChannelMat(_cameraId);

                    lock (_olock)
                    {
                        OS.Spin.Running.Cache.GetInstance().Mats[_cameraId] = threeMat;
                    }

                    LogisTrac.WriteInfoLog(String.Format("[检测] 结束 ={0}======[{1}]", _cameraId, count));
                    if (count <= 0)
                    {
                        cache.SetFore_Result(_cameraId, new List<Modle.Sdk.StructInfos.Fore_Result>());
                        continue;
                    }

                    // 解析返回结果
                    for (var i = 0; i < count; i++)
                    {
                        var ptr = (pt1 + i * Marshal.SizeOf(typeof(Modle.Sdk.StructInfos.Fore_Result)));
                        results.Add((Modle.Sdk.StructInfos.Fore_Result)Marshal.PtrToStructure(ptr, typeof(Modle.Sdk.StructInfos.Fore_Result)));
                    }

                    cache.SetFore_Result(_cameraId, results);
                }
                catch (Exception ex)
                {
                    LogisTrac.WriteLog(string.Format("Run:{0}", ex.Message));
                }
                finally
                {
                    Marshal.FreeHGlobal(pt1);
                    while (!_semaphorePool.Release(string.Format("{0}{1}", OS.Spin.Running.Infos.Names.S_DETECTION_OK, _cId)))
                    {
                        Thread.Sleep(10);
                    }
                }

            }
        }

        public void DoUploadClothsKind(int cloths_kind)
        {
            #region TWB20210902
            detcPara.cloths_kind = cloths_kind;
            //OS.Spin.SdkLayer.SdkMyCode.Flaw_UpdateDict(_initHandle, cloths_kind);方法已删除
            #endregion
        }

        public void Dispose()
        {
            _runThread.Abort();
            #region TWB20210902
            OS.Spin.SdkLayer.SdkMyCode.Flaw_DetecRelease(ref _initHandle);
            #endregion
        }
    }
}