c#联合Halcon进行OCR字符识别(含halcon-25.05 百度网盘)

1.下载安装halcon

通过网盘分享的文件:halcon-25.05.0.0-x64-win64

链接: https://pan.baidu.com/s/1XAx-8ZQM-ZHkgHIc-dhCYw

提取码: whek

2.c#环境配置

创建test_halcon_ocr项目

找到halcon的安装路径

我的:

D:\halcon\HALCON-25.05-Progress\bin\x64-win64

D:\halcon\HALCON-25.05-Progress\bin\dotnet35

添加引用("D:\halcon\HALCON-25.05-Progress\bin\dotnet35\halcondotnet.dll")

把halcondotnet.dll拖到工具箱中。

屏幕录制 2025-08-12 103356

添加HWindowcontrol ,button 和 textbox

设置button1 点击事件

cs 复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HalconDotNet;

namespace test_halcon_ocr
{
    public partial class Form1 : Form
    {
        HObject TestImage;
        string Path_testimg = "C:\\Users\\86957\\Desktop\\img_ocr_0296.png";


        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            //读取文件
            HOperatorSet.ReadImage(out TestImage, Path_testimg);
            //获取图片大小
            HTuple Width, Height;
            HOperatorSet.GetImageSize(TestImage, out Width, out Height);
            //设置图片显示范围 hWindowControl1.HalconWindow获得窗体句柄
            HOperatorSet.SetPart(hWindowControl1.HalconWindow, 0, 0, (Height - 1), (Width - 1)); //0,0, (Height - 1), (Width - 1)代表从0,0坐标到图片的宽高坐标,达到全屏显示

            //将图片投射到窗体上
            HOperatorSet.DispObj(TestImage, hWindowControl1.HalconWindow);//将TestImage变量投射到句柄窗口上


        }

        private void button2_Click(object sender, EventArgs e)
        {

        }
    }
}

运行,

成功报错。

解决:

项目右键属性,找到生成,取消勾选首选32位。

再次运行,

成功。

3. ocr 字符识别

  1. CreateDeepOcr函数:这个函数负责创建深度OCR处理器。使用HOperatorSet.CreateDeepOcr方法,传入参数"mode"和"recognition",生成一个OCR句柄。然后调用set_suitable_device_in_ocr_handle来设置合适的运行设备(如GPU或CPU),并设置识别图像的宽度参数。这个函数的作用是初始化OCR模型,准备后续的识别操作。

  2. set_suitable_device_in_ocr_handle函数:该函数用于配置OCR处理器使用的计算设备。首先查询可用的深度学习设备(GPU和CPU),优先选择GPU。然后设置识别图像的宽度参数,确保在处理时不会因为内存问题出错。这里涉及到异常处理,确保在设备不可用时能够回退到其他设备,并在最后恢复默认的图像宽度设置。

  3. DeepLearningOCR函数:这是实际的OCR识别函数。它接收图像、ROI坐标、窗口句柄和OCR处理器句柄作为参数。处理步骤包括图像预处理(均值滤波和强调处理)、裁剪ROI区域、应用OCR识别,并将结果返回。识别过程中使用Halcon的ApplyDeepOcr方法,并从结果中提取识别的文本。

运行后,

4.完整代码:

cs 复制代码
using System;
using System.IO;
using System.Windows.Forms;
using HalconDotNet;
namespace test_halcon_ocr
{
    public partial class Form1 : Form
    {
        HObject TestImage;
        HTuple hv_DeepOcrHandle = new HTuple();
        string Path_testimg = "C:\\Users\\86957\\Desktop\\img_ocr_0296.png";


        public Form1()
        {
            InitializeComponent();
        }


        //自动选择最佳计算设备(GPU优先),优化模型运行效率
        static void set_suitable_device_in_ocr_handle(HTuple hv_DeepOcrHandle)
        {



            // Local control variables 

            HTuple hv_DLDeviceHandles = new HTuple(), hv_RecognitionImageWidthDefault = new HTuple();
            HTuple hv_Exception = new HTuple(), hv_Index = new HTuple();
            // Initialize local and output iconic variables 
            try
            {
                //Determine deep learning device to work with (prefer GPU over CPU).
                hv_DLDeviceHandles.Dispose();
                HOperatorSet.QueryAvailableDlDevices((new HTuple("runtime")).TupleConcat("runtime"),
                    (new HTuple("gpu")).TupleConcat("cpu"), out hv_DLDeviceHandles);
                if ((int)(new HTuple((new HTuple(hv_DLDeviceHandles.TupleLength())).TupleEqual(
                    0))) != 0)
                {
                    throw new HalconException("No supported device found to continue this example.");
                }
                //Set recognition_image_width larger for the example to work without memory problems.
                try
                {
                    hv_RecognitionImageWidthDefault.Dispose();
                    HOperatorSet.GetDeepOcrParam(hv_DeepOcrHandle, "recognition_image_width",
                        out hv_RecognitionImageWidthDefault);
                    HOperatorSet.SetDeepOcrParam(hv_DeepOcrHandle, "recognition_image_width",
                        260);
                }
                // catch (Exception) 
                catch (HalconException HDevExpDefaultException1)
                {
                    HDevExpDefaultException1.ToHTuple(out hv_Exception);
                }

                for (hv_Index = 0; (int)hv_Index <= (int)((new HTuple(hv_DLDeviceHandles.TupleLength()
                    )) - 1); hv_Index = (int)hv_Index + 1)
                {
                    try
                    {
                        using (HDevDisposeHelper dh = new HDevDisposeHelper())
                        {
                            HOperatorSet.SetDeepOcrParam(hv_DeepOcrHandle, "device", hv_DLDeviceHandles.TupleSelect(
                                hv_Index));
                        }
                        break;
                    }
                    // catch (Exception) 
                    catch (HalconException HDevExpDefaultException1)
                    {
                        HDevExpDefaultException1.ToHTuple(out hv_Exception);
                        if ((int)(new HTuple(hv_Index.TupleEqual((new HTuple(hv_DLDeviceHandles.TupleLength()
                            )) - 1))) != 0)
                        {
                            throw new HalconException("Could not set any of the supported devices to continue this example.");
                        }
                    }
                }
                //Reset recognition_image_width to the default value.
                try
                {
                    HOperatorSet.SetDeepOcrParam(hv_DeepOcrHandle, "recognition_image_width",
                        hv_RecognitionImageWidthDefault);
                }
                // catch (Exception) 
                catch (HalconException HDevExpDefaultException1)
                {
                    HDevExpDefaultException1.ToHTuple(out hv_Exception);
                }


                hv_DLDeviceHandles.Dispose();
                hv_RecognitionImageWidthDefault.Dispose();
                hv_Exception.Dispose();
                hv_Index.Dispose();

                return;
            }
            catch (HalconException HDevExpDefaultException)
            {

                hv_DLDeviceHandles.Dispose();
                hv_RecognitionImageWidthDefault.Dispose();
                hv_Exception.Dispose();
                hv_Index.Dispose();

                throw HDevExpDefaultException;
            }
        }


        //执行完整的OCR识别流程,包含预处理、ROI裁剪、模型推理和结果解析
        public static string DeepLearningOCR(HObject ho_ImageSource, int row1, int col1, int row2, int col2, HWindow Window, HTuple hv_DeepOcrHandle)
        {


            // Local iconic variables 

            HObject ho_ImageMean, ho_Image;
            HObject ho_ImageWord, ho_Rectangle;

            // Local control variables 

            HTuple hv_Width = new HTuple();
            HTuple hv_Height = new HTuple(), hv_DeepOcrResult = new HTuple();
            HTuple hv_RecognizedWord = new HTuple();
            // Initialize local and output iconic variables 
            //HOperatorSet.GenEmptyObj(out ho_ImageSource);
            HOperatorSet.GenEmptyObj(out ho_ImageMean);
            HOperatorSet.GenEmptyObj(out ho_Image);
            HOperatorSet.GenEmptyObj(out ho_ImageWord);
            HOperatorSet.GenEmptyObj(out ho_Rectangle);
            try
            {

                ho_ImageMean.Dispose();
                HOperatorSet.MeanImage(ho_ImageSource, out ho_ImageMean, 3, 3);// 图像预处理

                ho_Image.Dispose();
                HOperatorSet.Emphasize(ho_ImageMean, out ho_Image, 9, 9, 1);

                hv_Width.Dispose(); hv_Height.Dispose();
                HOperatorSet.GetImageSize(ho_ImageSource, out hv_Width, out hv_Height);

                //
                //Crop the word to be recognized by the recognition component.
                ho_ImageWord.Dispose();
                HOperatorSet.CropRectangle1(ho_Image, out ho_ImageWord, row1, col1, row2, col2);// ROI裁剪
                ho_Rectangle.Dispose();
                HOperatorSet.GenRectangle1(out ho_Rectangle, row1, col1, row2, col2);
                //
                //Apply recognition with default recognition_image_width.

                hv_DeepOcrResult.Dispose();
                HOperatorSet.ApplyDeepOcr(ho_ImageWord, hv_DeepOcrHandle, "recognition", out hv_DeepOcrResult);  // 执行OCR识别
                hv_RecognizedWord.Dispose();
                HOperatorSet.GetDictTuple(hv_DeepOcrResult, "word", out hv_RecognizedWord);
                ho_Image.DispObj(Window);

                Window.SetDraw("margin");

                Window.SetColor("red");
                Window.SetPart(0, 0, (int)(hv_Height - 1), (int)(hv_Width - 1));


                ho_Rectangle.DispObj(Window);



            }
            catch (HalconException HDevExpDefaultException)
            {
                ho_ImageSource.Dispose();
                ho_ImageMean.Dispose();
                ho_Image.Dispose();
                ho_ImageWord.Dispose();
                ho_Rectangle.Dispose();

                // hv_DeepOcrHandle.Dispose();
                hv_Width.Dispose();
                hv_Height.Dispose();
                hv_DeepOcrResult.Dispose();
                hv_RecognizedWord.Dispose();

                throw HDevExpDefaultException;
            }
            ho_ImageSource.Dispose();
            ho_ImageMean.Dispose();
            ho_Image.Dispose();
            ho_ImageWord.Dispose();
            ho_Rectangle.Dispose();

            //  hv_DeepOcrHandle.Dispose();
            hv_Width.Dispose();
            hv_Height.Dispose();
            hv_DeepOcrResult.Dispose();
            hv_RecognizedWord.Dispose();

            return hv_RecognizedWord.S;

        }


        //初始化深度学习OCR模型,创建识别器实例并配置基本参数
        public static HTuple CreateDeepOcr()
        {
            HTuple hv_DeepOcrHandle = new HTuple();
            hv_DeepOcrHandle.Dispose();
            HOperatorSet.CreateDeepOcr("mode", "recognition", out hv_DeepOcrHandle);
            set_suitable_device_in_ocr_handle(hv_DeepOcrHandle);
            HOperatorSet.SetDeepOcrParam(hv_DeepOcrHandle, "recognition_image_width", 260);
            return hv_DeepOcrHandle;

        }

        private void button1_Click(object sender, EventArgs e)//显示图像
        {
            //读取文件
            HOperatorSet.ReadImage(out TestImage, Path_testimg);
            //获取图片大小
            HTuple Width, Height;
            HOperatorSet.GetImageSize(TestImage, out Width, out Height);
            //设置图片显示范围 hWindowControl1.HalconWindow获得窗体句柄
            HOperatorSet.SetPart(hWindowControl1.HalconWindow, 0, 0, (Height - 1), (Width - 1)); //0,0, (Height - 1), (Width - 1)代表从0,0坐标到图片的宽高坐标,达到全屏显示

            //将图片投射到窗体上
            HOperatorSet.DispObj(TestImage, hWindowControl1.HalconWindow);//将TestImage变量投射到句柄窗口上


        }


        private void button2_Click(object sender, EventArgs e)//字符识别
        {

            textBox1.AppendText("开始检测:" + "\r\n");
            try
            {
                hv_DeepOcrHandle = CreateDeepOcr();

            }
            catch
            {
                MessageBox.Show("error");
            }


            if (!File.Exists(Path_testimg))
            {
                textBox1.AppendText($"文件不存在: {Path_testimg}" + "\r\n");
                return;
            }


            HalconDotNet.HImage hImage = new HalconDotNet.HImage(Path_testimg);


            HTuple width, height;
            hImage.GetImageSize(out width, out height);

            int intWidth = width.TupleInt();
            int intHeight = height.TupleInt();
            textBox1.AppendText("选框坐标为:" + "\r\n");
            textBox1.AppendText(intWidth.ToString());
            textBox1.AppendText(width.ToString() + "\r\n");




            string code = DeepLearningOCR(hImage, 0, 0, intHeight, intWidth, hWindowControl1.HalconWindow, hv_DeepOcrHandle);
            textBox1.AppendText("code:" + code + "\r\n");





        }
    }
}
cs 复制代码
namespace test_halcon_ocr
{
    partial class Form1
    {
        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows 窗体设计器生成的代码

        /// <summary>
        /// 设计器支持所需的方法 - 不要修改
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            this.hWindowControl1 = new HalconDotNet.HWindowControl();
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // hWindowControl1
            // 
            this.hWindowControl1.BackColor = System.Drawing.Color.Black;
            this.hWindowControl1.BorderColor = System.Drawing.Color.Black;
            this.hWindowControl1.ImagePart = new System.Drawing.Rectangle(0, 0, 640, 480);
            this.hWindowControl1.Location = new System.Drawing.Point(96, 116);
            this.hWindowControl1.Name = "hWindowControl1";
            this.hWindowControl1.Size = new System.Drawing.Size(525, 338);
            this.hWindowControl1.TabIndex = 0;
            this.hWindowControl1.WindowSize = new System.Drawing.Size(525, 338);
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(174, 567);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(288, 117);
            this.button1.TabIndex = 1;
            this.button1.Text = "button1";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // button2
            // 
            this.button2.Location = new System.Drawing.Point(662, 567);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(242, 117);
            this.button2.TabIndex = 2;
            this.button2.Text = "button2";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.button2_Click);
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(830, 189);
            this.textBox1.Multiline = true;
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(317, 254);
            this.textBox1.TabIndex = 3;
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 18F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(1269, 736);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.hWindowControl1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private HalconDotNet.HWindowControl hWindowControl1;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
        private System.Windows.Forms.TextBox textBox1;
    }
}
相关推荐
时光追逐者5 小时前
C#/.NET/.NET Core技术前沿周刊 | 第 49 期(2025年8.1-8.10)
c#·.net·.netcore
★YUI★6 小时前
学习游制作记录(背包UI以及各种物品的存储)8.12
学习·游戏·ui·unity·c#
专注VB编程开发20年6 小时前
IIS Express中可以同时加载并使用.net4.0和.NET 2.0的 DLL
c++·windows·microsoft·c#·vb.net
悦人楼8 小时前
当C#遇上Notepad++:实现GCode可视化编辑的跨界实践
java·c#·notepad++
大飞pkz9 小时前
【C#】正则表达式
开发语言·正则表达式·c#·string·字符串匹配·高效字符串匹配
fs哆哆13 小时前
在VB.net中,委托Action和Func,结合LINQ和Lambda表达式的应用
c#·.net·linq
向宇it13 小时前
【unity实战】在Unity中实现不规则模型的网格建造系统(附项目源码)
游戏·3d·unity·c#·游戏引擎
CodeCraft Studio14 小时前
3D文档控件Aspose.3D实用教程:在 C# 中将 3MF 文件转换为 STL
c++·3d·c#
专注VB编程开发20年14 小时前
C#教程之NPOI读写excel文件XLS,XLSX格式
数据库·microsoft·c#·excel·xlsx·xls