介绍+
winform与halcon结合标准化工具实例
软件架构
软件架构说明 基于NET6 WINFORM+HALCON
实现标准化视觉检测工具
集成相机通讯
集成PLC通讯
TCP等常见通讯
支持常见halcon算子
- 图形采集
- blob分析
- 高精度匹配
- 颜色提取
- 找几何体
- 二维码提取
- OCR识别
- 等等

。。。

安装教程
https://dotnet.microsoft.com/zh-cn/download/dotnet/6.0
使用说明
安装 NET6 SDK,编译即可运行
对入门的同学应该有较好的学习意义
本项目涵盖了标准化视觉检测工具的大部分功能,有兴趣的小伙伴可以请我吃一顿肯德基,获取源码进行学习。
using System;
 using System.Collections.Generic;
 using System.Drawing;
 using System.Drawing.Imaging;
 using System.Linq;
 using System.Reflection.Emit;
 using System.Runtime.InteropServices;
 using System.Text;
 using System.Threading.Tasks;
 using HalconDotNet;
 using MT_OCR5._0;
 using PaddleOCRSharp;
namespace Vision.Winform.Algorithm
 {   //识别各种二维码,一维码, 字符识别
    namespace MT_code
     {
         public class QR
         {
             public ToolPar toolPar = new ToolPar();
             public bool status = true;
             internal HObject image = null;
            //二维码识别句柄
             internal HTuple modelID = null;
            public string CodeType = "QR Code";
             public string ParamName = "default_parameters";
             public string ParamValue = "standard_recognition";
            private void creathandle()
             {
                 try
                 {
                     switch (toolPar.RunPar.QrMode)
                     {
                         case QrMode.QR:
                             CodeType = "QR Code";
                             break;
                         case QrMode.DM:
                             CodeType = "Data Matrix ECC 200";
                             break;
                     }
                    switch (toolPar.RunPar.QrRecognition)
                     {
                         case QRRecognition.standard_recognition:
                             ParamValue = "standard_recognition";
                             break;
                         case QRRecognition.enhanced_recognition:
                             ParamValue = "enhanced_recognition";
                             break;
                         case QRRecognition.maximum_recognition:
                             ParamValue = "maximum_recognition";
                             break;
                     }
                     if(modelID == null)
                     {
                         HOperatorSet.CreateDataCode2dModel((HTuple)CodeType, (HTuple)ParamName, (HTuple)ParamValue, out modelID);
                     }
                }
                 catch (Exception)
                 {
                     status = false;
                 }
                //return 0;
             }
            private void clearhandle()
             {
                 HOperatorSet.ClearDataCode2dModel(modelID);
             }
            public void run()
             {
                 creathandle();
                 try
                 {
                     toolPar.ResultPar.CodeResult = new List<BarcodeResult>();
                     if (modelID == null)
                     {
                         status = false;
                         return;
                     }
                     if (toolPar.InputPar.图像 != null)
                     {
                         if (toolPar.InputPar.ROI != null)
                         {
                             HOperatorSet.ReduceDomain(toolPar.InputPar.图像, toolPar.InputPar.ROI, out image);
                         }
                         else
                         {
                             image = toolPar.InputPar.图像;
                         }
                         //设置极性
                         string codePolarity= "dark_on_light";
                         switch (toolPar.RunPar.CodePolarity)
                         {
                             case CodePolarity.any: codePolarity = "any"; break;
                             case CodePolarity.positive: codePolarity = "dark_on_light"; break;
                             case CodePolarity.negative: codePolarity = "light_on_dark"; break;
                         }
                         HOperatorSet.SetDataCode2dParam(modelID, "polarity", codePolarity);
                         HOperatorSet.SetDataCode2dParam(modelID, "timeout", toolPar.RunPar.TimeOut);
                         HObject xlds;
                         HTuple strtmp, resultHandles;
                         HOperatorSet.FindDataCode2d(image,
                             out xlds,
                             modelID,
                             "stop_after_result_num", toolPar.RunPar.CodeNum,
                             out resultHandles,
                             out strtmp);
                         //把结果塞进去
                         for (int i = 0; i < strtmp.Length; i++)
                         {
                             BarcodeResult tmp;
                             HObject region;
                             HOperatorSet.GenRegionContourXld(xlds, out region, "filled");
                             tmp.region = region;
                             tmp.code = strtmp[i].S;
                             toolPar.ResultPar.CodeResult.Add(tmp);
                         }
                         toolPar.ResultPar.CodeNum = strtmp.Length;
//HOperatorSet.clear
                    }
                     else
                     {
                         status = false;
                         return;
                     }
                }
                 catch (Exception)
                 {
                     clearhandle();
                     status = false;
                 }
                 clearhandle();
             }
            [Serializable]
             public class ToolPar : ToolParBase
             {
                 private InputPar _inputPar = new InputPar();
                 public InputPar InputPar
                 {
                     get { return _inputPar; }
                     set { _inputPar = value; }
                 }
                private RunPar _runPar = new RunPar();
                 public RunPar RunPar
                 {
                     get { return _runPar; }
                     set { _runPar = value; }
                 }
                private ResultPar _resultPar = new ResultPar();
                 public ResultPar ResultPar
                 {
                     get { return _resultPar; }
                     set { _resultPar = value; }
                 }
             }
             [Serializable]
             public class InputPar
             {
                 private HObject _图像;
                 public HObject 图像
                 {
                     get { return _图像; }
                     set { _图像 = value; }
                 }
                private HObject _ROI;
                 public HObject ROI
                 {
                     get { return _ROI; }
                     set { _ROI = value; }
                 }
                private HObject _屏蔽区域;
                 public HObject 屏蔽区域
                 {
                     get { return _屏蔽区域; }
                     set { _屏蔽区域 = value; }
                 }
public int FindCodeNum { set; get; } = 1;
             }
             [Serializable]
             public class RunPar
             {
                 public QRRecognition QrRecognition { get; set; }
                 public QrMode QrMode { get; set; }
                 public CodePolarity CodePolarity { get; set; }
public int TimeOut { get; set; }
                public int CodeNum { get; set; }
             }
             [Serializable]
             public class ResultPar
             {
                 private List<BarcodeResult> _CodeResult;
                 public List<BarcodeResult> CodeResult
                 {
                     get { return _CodeResult; }
                     set { _CodeResult = value; }
                 }
                private int _CodeNum;
                 public int CodeNum
                 {
                     get { return _CodeNum; }
                     set { _CodeNum = value; }
                 }
             }
         }
        public class One_dimension
         {
             public ToolPar toolPar = new ToolPar();
             public bool status = true;
             internal HObject image = null;
            //条形码识别句柄
             internal HTuple modelID = null;
             internal HTuple codetype = "auto";
            private void creathandle()
             {
                 try
                 {
                     HOperatorSet.CreateBarCodeModel(new HTuple(), new HTuple(), out modelID);
                 }
                 catch (Exception)
                 {
                     status = false;
                 }
                //return 0;
             }
            private void clearhandle()
             {
                 HOperatorSet.ClearBarCodeModel(modelID);
             }
            public void run()
             {
                 creathandle();
                 toolPar.ResultPar.CodeResult = new List<BarcodeResult>();
                 try
                 {
                     if (modelID == null)
                     {
                         status = false;
                         return;
                     }
                     if (toolPar.InputPar.图像 != null)
                     {
                         if (toolPar.InputPar.ROI != null)
                         {
                             HOperatorSet.ReduceDomain(toolPar.InputPar.图像, toolPar.InputPar.ROI, out image);
                         }
                         else
                         {
                             image = toolPar.InputPar.图像;
                         }
                         HObject region;
                         HTuple strtmp;
                        HOperatorSet.SetBarCodeParam(modelID, "timeout", toolPar.RunPar.TimeOut);
                         HOperatorSet.SetBarCodeParam(modelID, "stop_after_result_num", toolPar.RunPar.CodeNum);
                        设置极性
                         //string codePolarity = "dark_on_light";
                         //switch (toolPar.RunPar.CodePolarity)
                         //{
                         //    case CodePolarity.any: codePolarity = "any"; break;
                         //    case CodePolarity.positive: codePolarity = "dark_on_light"; break;
                         //    case CodePolarity.negative: codePolarity = "light_on_dark"; break;
                         //}
                         //HOperatorSet.SetBarCodeParam(modelID, "polarity", codePolarity);
                         HOperatorSet.FindBarCode(image, out region, modelID, codetype, out strtmp);
                        //把结果塞进去
                         for (int i = 0; i < strtmp.Length; i++)
                         {
                             BarcodeResult tmp;
                             tmp.region = region;
                             tmp.code = strtmp[i].S;
                             toolPar.ResultPar.CodeResult.Add(tmp);
                         }
                         toolPar.ResultPar.CodeNum = strtmp.Length;
//HOperatorSet.clear
                    }
                     else
                     {
                         status = false;
                         return;
                     }
                }
                 catch (Exception)
                 {
                     clearhandle();
                     status = false;
                 }
                 clearhandle();
             }
             [Serializable]
             public class ToolPar : ToolParBase
             {
                 private InputPar _inputPar = new InputPar();
                 public InputPar InputPar
                 {
                     get { return _inputPar; }
                     set { _inputPar = value; }
                 }
                private RunPar _runPar = new RunPar();
                 public RunPar RunPar
                 {
                     get { return _runPar; }
                     set { _runPar = value; }
                 }
                private ResultPar _resultPar = new ResultPar();
                 public ResultPar ResultPar
                 {
                     get { return _resultPar; }
                     set { _resultPar = value; }
                 }
             }
             [Serializable]
             public class InputPar
             {
                 private HObject _图像;
                 public HObject 图像
                 {
                     get { return _图像; }
                     set { _图像 = value; }
                 }
                private HObject _ROI;
                 public HObject ROI
                 {
                     get { return _ROI; }
                     set { _ROI = value; }
                 }
                private HObject _屏蔽区域;
                 public HObject 屏蔽区域
                 {
                     get { return _屏蔽区域; }
                     set { _屏蔽区域 = value; }
                 }
            }
             [Serializable]
             public class RunPar
             {
                 //public BarRecognition BarRecognition { get; set; }
                 public BarMode BarMode { get; set; }
                 public CodePolarity CodePolarity { get; set; }
public int TimeOut { get; set; }
                public int CodeNum { get; set; }
             }
             [Serializable]
             public class ResultPar
             {
                 private List<BarcodeResult> _CodeResult;
                 public List<BarcodeResult> CodeResult
                 {
                     get { return _CodeResult; }
                     set { _CodeResult = value; }
                 }
                private int _CodeNum;
                 public int CodeNum
                 {
                     get { return _CodeNum; }
                     set { _CodeNum = value; }
                 }
             }
         }
        public class OCR
         {
             public ToolPar toolPar = new ToolPar();
             public bool status = true;
             internal HObject image = null;
             RunPar runPar=new RunPar ();
             public void run()
             {
                try
                 {
                     if (toolPar.InputPar.图像 != null)
                     {
                         if (toolPar.InputPar.ROI != null && toolPar.InputPar.屏蔽区域 != null)
                         {
                             HObject reduce_region = new HObject();
                             reduce_region.Dispose();
                             HOperatorSet.Difference(toolPar.InputPar.ROI, toolPar.InputPar.屏蔽区域, out reduce_region);
                             //image.Dispose();
                             HOperatorSet.ReduceDomain(toolPar.InputPar.图像, reduce_region, out image);
                             HOperatorSet.CropDomain(image, out image);
                             reduce_region.Dispose();
                         }
                         else if (toolPar.InputPar.ROI != null && toolPar.InputPar.屏蔽区域 == null)
                         {
                             HOperatorSet.GenEmptyObj(out image);
                             HOperatorSet.ReduceDomain(toolPar.InputPar.图像, toolPar.InputPar.ROI, out image);
                             HOperatorSet.CropDomain(image, out image);
                         }
                         else if (toolPar.InputPar.ROI == null && toolPar.InputPar.屏蔽区域 != null)
                         {
                             HObject reduce_region = new HObject();
                             reduce_region.Dispose();
                             HOperatorSet.Difference(toolPar.InputPar.图像, toolPar.InputPar.屏蔽区域, out reduce_region);
                             //image.Dispose();
                             HOperatorSet.ReduceDomain(toolPar.InputPar.图像, reduce_region, out image);
                             HOperatorSet.CropDomain(image, out image);
                             reduce_region.Dispose();
                         }
                         else
                         {
                             if (image != null)
                                 image.Dispose();
                             image = toolPar.InputPar.图像;
                         }
                     }
                     else
                     {
                         status = false;
                         return;
                     }
                     //初始化
                     //ocr_engine.OCR_INIT();
                     //HObject img;
                     //HOperatorSet.GenEmptyObj(out img);
                     //img = image;
                     检测
                     //string ocr_result = ocr_engine.OCR_Dect(img);
                     //ocr_engine.engine.Dispose();
                     //toolPar.ResultPar.OCRResult = ocr_result;
                     //ocr_result = String.Empty;
                    HOperatorSet.CountChannels(image, out var channels);
                     Bitmap img;
                     HObject multiChannelImage;
                     HOperatorSet.GenEmptyObj(out multiChannelImage);
                     if (channels == 3)
                     {
                         img=runPar.Honject2Bitmap24(image);
                     }
                     else
                     {
                         HOperatorSet.Compose3(image, image, image, out multiChannelImage);
                         img = runPar.Honject2Bitmap24(multiChannelImage);
                     }
                     runPar.ocrResult= runPar.engine.DetectText(img);
                     toolPar.ResultPar.OCRResult = runPar.ocrResult.Text;
                 }
                 catch (Exception)
                 {
                     status = false;
                 }
             }
            [Serializable]
             public class ToolPar : ToolParBase
             {
                 private InputPar _inputPar = new InputPar();
                 public InputPar InputPar
                 {
                     get { return _inputPar; }
                     set { _inputPar = value; }
                 }
                private RunPar _runPar = new RunPar();
                 public RunPar RunPar
                 {
                     get { return _runPar; }
                     set { _runPar = value; }
                 }
                private ResultPar _resultPar = new ResultPar();
                 public ResultPar ResultPar
                 {
                     get { return _resultPar; }
                     set { _resultPar = value; }
                 }
             }
             [Serializable]
             public class InputPar
             {
                 private HObject _图像;
                 public HObject 图像
                 {
                     get { return _图像; }
                     set { _图像 = value; }
                 }
                private HObject _ROI;
                 public HObject ROI
                 {
                     get { return _ROI; }
                     set { _ROI = value; }
                 }
                private HObject _屏蔽区域;
                 public HObject 屏蔽区域
                 {
                     get { return _屏蔽区域; }
                     set { _屏蔽区域 = value; }
                 }
             }
             [Serializable]
             public class RunPar
             {
                 public OCRModelConfig config = null;
public OCRParameter oCRParameter = new OCRParameter();
public OCRResult ocrResult = new OCRResult();
public PaddleOCREngine engine;
                public RunPar()
                 {
                     engine = new PaddleOCREngine(config, oCRParameter);
                 }
                [DllImport("kernel32.dll")]
                 public static extern void CopyMemory(int Destination, int add, int Length);
                public Bitmap Honject2Bitmap24(HObject hObject)
                 {
                     HTuple width = new HTuple();
                     HTuple height = new HTuple();
                     HTuple pointer = new HTuple();
                     HTuple type = new HTuple();
                     HTuple width2 = new HTuple();
                     HTuple height2 = new HTuple();
                     HObject interleavedImage = new HObject();
                     HOperatorSet.GetImageSize(hObject, out width, out height);
                     HOperatorSet.InterleaveChannels(hObject, out interleavedImage, "rgb", 4 * width, 0);
                     HOperatorSet.GetImagePointer1(interleavedImage, out pointer, out type, out width2, out height2);
                     IntPtr scan = pointer;
                     return new Bitmap(width2 / 4, height2, width2, PixelFormat.Format24bppRgb, scan);
                 }
                public void HObject2Bitmap8(HObject image, out Bitmap res)
                 {
                     HOperatorSet.GetImagePointer1(image, out var pointer, out var _, out var width, out var height);
                     res = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
                     ColorPalette palette = res.Palette;
                     for (int i = 0; i <= 255; i++)
                     {
                         palette.Entries[i] = Color.FromArgb(255, i, i, i);
                     }
                    res.Palette = palette;
                     System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, width, height);
                     BitmapData bitmapData = res.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
                     int num = Image.GetPixelFormatSize(bitmapData.PixelFormat) / 8;
                     IntPtr scan = bitmapData.Scan0;
                     IntPtr source = pointer;
                     int num2 = width * height;
                     byte[] array = new byte[num2];
                     Marshal.Copy(source, array, 0, num2);
                     Marshal.Copy(array, 0, scan, num2);
                     res.UnlockBits(bitmapData);
                 }
             }
             [Serializable]
             public class ResultPar
             {
                 private string _OCRResult { get; set; }
                 public string OCRResult { get { return _OCRResult; } set { _OCRResult = value; } }
             }
}
    }
 }