HDCodeLearnHelper.cs 14.2 KB
using HalconDotNet; 
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CodeLibrary
{

    public class HDCodeLearnHelper
    {
        /// <summary>
        /// 图片对象,学习时如果使用图片学习,需要先设置此属性
        /// </summary>
        public static HObject DefaultImage = null;
        public static Bitmap DefaultBitmap = null;
        /// <summary>
        /// 学习后是否自动测试,默认是
        /// </summary>
        public static bool IsNeedTest = true;
       /// <summary>
       /// 是否正在学习中
       /// </summary>
        public static bool IsRun = false;
        internal static List<string> cameraNameList = new List<string>();
        internal static List<string> codeTypeList = new List<string>();

        private static char spiltChar = '#';
        /// <summary>
        /// 初始化摄像机名称和二维码类型
        /// </summary>
        /// <param name="nameStr">摄像机名称,多个用#分割</param>
        /// <param name="codeStr">二维码类型,多个用#分割</param>
        public static void LoadConfig(string nameStr, string codeStr)
        {
            cameraNameList = new List<string>();
            codeTypeList = new List<string>();
            try
            {

                string[] nameArray = nameStr.Split(spiltChar);
                foreach (string str in nameArray)
                {
                    HDLogUtil.info("加载到摄像机名称:" + str.Trim());
                    cameraNameList.Add(str.Trim());
                }
                string[] codeArray = codeStr.Split(spiltChar);
                foreach (string str in codeArray)
                {
                    HDLogUtil.info("加载到二维码类型:" + str.Trim());
                    codeTypeList.Add(str.Trim());
                }
                if (codeTypeList.Count <= 0)
                {
                    codeTypeList.Add("Data Matrix ECC 200");
                    codeTypeList.Add("QR Code");
                }
            }
            catch (Exception ex)
            {
                HDLogUtil.error("解析摄像机配置出错:" + ex.StackTrace);
            }
        } 
        private static HTuple hv_AcqHandle = null;

        private static Stopwatch stopWatch = new Stopwatch();
         /// <summary>
         /// 开始学习二维码
         /// </summary>
         /// <param name="Window">显示的窗口</param>
         /// <param name="camerName">摄像机名称,使用图片学习传""</param>
         /// <param name="codeType">二维码类型</param>
         /// <param name="paramPath">二维码参数文件路径</param>
         /// <param name="codeCount">二维码数量</param>
         /// <param name="timeOutMs">超时时间,默认5000毫秒</param>
        public static void StartLearn(HWindow Window, string camerName, string codeType, string paramPath, int codeCount, int timeOutMs)
        {
             
            if (codeCount <= 0)
            {
                codeCount = 1;
            }
            if (timeOutMs <= 0)
            {
                timeOutMs = 5000;
            }
            if (camerName.Equals("") && DefaultImage == null)
            {
                return;
            }
            HDLogUtil.info("开始学习[" + camerName + "][" + codeType + "]  [" + codeCount + "]  [" + timeOutMs + "]");
            learnCode(Window, camerName, codeType, paramPath, codeCount, timeOutMs);
        }
        private static bool IsTestEnd = false;
        private static bool IsLearnEnd = false;
        public static void StopLearn()
        {
            IsTestEnd = true;
            IsLearnEnd = true;
            IsRun = false;
        }
        private static bool OpenCamera(string cameraName)
        {
            if (cameraName.Equals(""))
            {
                return true;
            }
            try
            {   //[1] HD USB Camera
                if (cameraName.ToUpper().Contains("USB") || (cameraName.ToUpper().Contains("[") && cameraName.ToUpper().Contains("]")))
                {
                    HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb", -1, "false", "default", cameraName, 0, -1, out hv_AcqHandle);
                }
                else
                {
                    HOperatorSet.OpenFramegrabber("GigEVision", 0, 0, 0, 0, 0, 0, "default", -1, "default", -1, "false", "default", cameraName, 0, -1, out hv_AcqHandle);
                }

                return true;
            }
            catch (Exception ex)
            {
                HDLogUtil.error("open camera [" + cameraName + "]error :" + ex.ToString() + "");
                CloseCamera(cameraName);
                return false;
            }
        }
        private static void CloseCamera(string cameraName)
        {
            if (cameraName.Equals(""))
            {
                return;
            }
            try
            {
                HOperatorSet.CloseFramegrabber(hv_AcqHandle);
                hv_AcqHandle = null;
            }
            catch (Exception ex)
            {
                HDLogUtil.error("close camera[" + cameraName + "]error:" + ex.ToString());
            }
        }
       private static HObject GetImage(string cameraName)
        {
            if (cameraName.Equals(""))
            {
                return DefaultImage;
            }
            else
            {
                HObject ho_Image = null;
                HOperatorSet.GenEmptyObj(out ho_Image);
                ho_Image.Dispose();
                HOperatorSet.GrabImageAsync(out ho_Image, hv_AcqHandle, -1);
                return ho_Image;
            }
        }

        private static List<string> findCode = new List<string>();
        // Main procedure 
        private static bool learnCode(HWindow hv_ExpDefaultWinHandle, string cameraName, string codeType, string paramPath, int codeCount, int timeOutMs)
        { 
            stopWatch.Restart();
            IsRun = true;
            IsLearnEnd = false;
            IsTestEnd = false;
            try
            {
                HTuple hv_code_type = codeType;
                HTuple hv_model_path = paramPath; 
                HObject ho_SymbolXLDs = null; 
                HTuple hv_train_first = null, /*hv_AcqHandle = null,*/ hv_DataCodeHandle = null;
                HTuple hv_ResultHandles = new HTuple(), hv_DecodedDataStrings = new HTuple();
                HTuple hv_GenParamNames = new HTuple(), hv_ModelBeforeTraining = new HTuple();
         
               
                HOperatorSet.GenEmptyObj(out ho_SymbolXLDs);
                findCode = new List<string>();
                hv_train_first = 1;
                if (!OpenCamera(cameraName))
                {
                    HDLogUtil.info("open camera [" + cameraName + "] fail,学习结束");
                    StopLearn();
                    return false;
                }
                if (File.Exists(hv_model_path))
                {
                    try
                    {
                        HOperatorSet.ReadDataCode2dModel(hv_model_path, out hv_DataCodeHandle);
                    }
                    catch (Exception ex)
                    {
                        HOperatorSet.CreateDataCode2dModel(hv_code_type, new HTuple(), new HTuple(), out hv_DataCodeHandle);
                    }
                }
                else
                { 
                    HOperatorSet.CreateDataCode2dModel(hv_code_type, new HTuple(), new HTuple(), out hv_DataCodeHandle);
                }
                if ((int)(hv_train_first) != 0)
                {
                    while (findCode.Count < codeCount && IsLearnEnd.Equals(false))
                    {

                        HObject ho_Image = GetImage(cameraName);
                        if (ho_Image != null)
                        {
                            ho_SymbolXLDs.Dispose();
                            HOperatorSet.FindDataCode2d(ho_Image, out ho_SymbolXLDs, hv_DataCodeHandle, "train", "all", out hv_ResultHandles, out hv_DecodedDataStrings);
                            if ((int)(new HTuple((new HTuple(hv_DecodedDataStrings.TupleLength())).TupleNotEqual(0))) != 0)
                            {
                                HOperatorSet.QueryDataCode2dParams(hv_DataCodeHandle, "get_model_params", out hv_GenParamNames);
                                HOperatorSet.GetDataCode2dParam(hv_DataCodeHandle, hv_GenParamNames, out hv_ModelBeforeTraining);
                                CodeResultAdd(hv_DecodedDataStrings, codeType, "学习");
                            }
                            ShowImage(hv_ExpDefaultWinHandle, ho_Image, ho_SymbolXLDs);
                            ho_Image.Dispose();
                        }
                        if (findCode.Count >= codeCount || stopWatch.ElapsedMilliseconds > timeOutMs)
                        {
                            HDLogUtil.info("  持续时间[" + stopWatch.ElapsedMilliseconds + "]数量[" + findCode.Count + "]结束学习");
                            break;
                        }
                        Thread.Sleep(500);
                    }

                    //*参数写入文件
                    //HDLogUtil.info("[" + cameraName + "][" + codeType + "]保存参数到文件【" + paramPath + "】");
                    HOperatorSet.WriteDataCode2dModel(hv_DataCodeHandle, hv_model_path);
                    HOperatorSet.ClearDataCode2dModel(hv_DataCodeHandle);
                }

                //Read the previously saved data code model
                findCode = new List<string>();
                HOperatorSet.ReadDataCode2dModel(hv_model_path, out hv_DataCodeHandle);
                while (findCode.Count < codeCount && IsTestEnd.Equals(false) && IsNeedTest)
                {
                    HObject ho_Image = GetImage(cameraName);
                  
                    if (ho_Image != null)
                    {
                        ho_SymbolXLDs.Dispose();
                        HOperatorSet.FindDataCode2d(ho_Image, out ho_SymbolXLDs, hv_DataCodeHandle, "stop_after_result_num", codeCount, out hv_ResultHandles, out hv_DecodedDataStrings);
                       ShowImage(hv_ExpDefaultWinHandle, ho_Image, ho_SymbolXLDs);
                        if ((int)(new HTuple((new HTuple(hv_DecodedDataStrings.TupleLength())).TupleNotEqual(0))) != 0)
                        {
                            CodeResultAdd(hv_DecodedDataStrings, codeType, "识别");
                        }
                        ho_Image.Dispose();
                    }
                    if (findCode.Count >= codeCount || stopWatch.ElapsedMilliseconds > timeOutMs)
                    {
                        HDLogUtil.info(" 持续时间[" + stopWatch.ElapsedMilliseconds + "]数量[" + findCode.Count + "]结束识别");
                        break;
                    }
                    Thread.Sleep(500);
                }

                HOperatorSet.ClearDataCode2dModel(hv_DataCodeHandle);

                CloseCamera(cameraName); 
                ho_SymbolXLDs.Dispose();              

                StopLearn();
                if (hv_code_type != null)
                {
                    hv_code_type.UnPinTuple();
                }
                if (hv_model_path != null)
                {
                    hv_model_path.UnPinTuple();
                }
                if (hv_train_first != null)
                {
                    hv_train_first.UnPinTuple();
                }
                if (hv_ResultHandles != null)
                {
                    hv_ResultHandles.UnPinTuple();
                }
                if (hv_DataCodeHandle != null)
                {
                    hv_DataCodeHandle.UnPinTuple();
                }
                if (hv_DecodedDataStrings != null)
                {
                    hv_DecodedDataStrings.UnPinTuple();
                }
                if (hv_GenParamNames != null)
                {
                    hv_GenParamNames.UnPinTuple();
                }
                if (hv_ModelBeforeTraining != null)
                {
                    hv_ModelBeforeTraining.UnPinTuple();
                }
                return true;
            }
            catch (Exception ex)
            {
                HDLogUtil.error("出错了:" + ex.ToString());
                CloseCamera(cameraName);
                StopLearn();
                return false;
            } 
        }

        private static void CodeResultAdd(HTuple hv_DecodedDataStrings, string codeType, string logname)
        {
            string[] resultList = hv_DecodedDataStrings.SArr;
            foreach (string str in resultList)
            {
                if (!findCode.Contains(str))
                {
                    findCode.Add(str);
                    HDLogUtil.info(" " + logname + "到二维码[" + str + "]");
                }
            }
        }



        private static void ShowImage(HWindow hv_ExpDefaultWinHandle, HObject ho_Image, HObject ho_SymbolXLDs)
        {
            HDCodeHelper.ShowImage(hv_ExpDefaultWinHandle, ho_Image, ho_SymbolXLDs);
            //if (hv_ExpDefaultWinHandle == null || ho_Image == null)
            //{
            //    return;
            //}
            //Task.Factory.StartNew(delegate ()
            //{
            //    try
            //    { 
            //        HTuple width, height;
            //        //int dWidth = 0; int dHeight = 0;
            //        HOperatorSet.GetImageSize(ho_Image, out width, out height);

            //        int dWidth = (int)width.D;
            //        int dHeight = (int)height.D;
            //        hv_ExpDefaultWinHandle.SetPart(0, 0, dHeight, dWidth);
            //        HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "red");
            //        HOperatorSet.SetLineWidth(hv_ExpDefaultWinHandle, new HTuple(2));
            //        HOperatorSet.DispObj(ho_Image, hv_ExpDefaultWinHandle);
            //        HOperatorSet.DispObj(ho_SymbolXLDs, hv_ExpDefaultWinHandle);
            //    }
            //    catch (Exception ex)
            //    {

            //    }
            //});
        }

    }


}