C# 通用OCR识别

一、前言

通过查看网络资料以及书籍资料,发现大多数OCR识别功能都是基于Python语言开发的,对于习惯使用C# 开发语言的程序猿们,岂不是一件很苦恼的事!当然想学习Python,掌握多一项技能也并不是坏事!为了方便使用,想使用C# 的往下看(或需要使用当作工作辅助也行,资源下载在最后有链接)。

二、开发要求

1、图形处理库Clipper、Emgu.CV

2、高性能推理引擎 Microsoft.ML.OnnxRuntime

3、借用PaddleOCR模型

4、现有功能,选择照片识别、截图识别,选择PDF文件识别

三、部分代码

cs 复制代码
using Emgu.CV;
using OcrDemo.Helpers;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace OcrDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private string fileFilter = "所有文件 (*.*)|*.*|bmp|*.bmp|jpg|*.jpg|jpeg|*.jpeg|png|*.png";
        private Bitmap bmp;  

        private string outPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "output");

        private Stopwatch stopwatch = new Stopwatch();

        private string filePath = "";

        private int threadNum = 4;


        private OcrLite ocrEngin;
        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                if (!Directory.Exists(outPath))
                {
                    Directory.CreateDirectory(outPath);
                }

                splitContainer1.SplitterDistance = (int)(splitContainer1.Width * 0.5);
                splitContainer2.SplitterDistance = (int)(splitContainer2.Width * 0.5);
                string appPath = AppDomain.CurrentDomain.BaseDirectory;
                string appDir = Directory.GetParent(appPath).FullName;

            }
            catch (Exception ex)
            {
                SetMessge(ex.Message);
            }
        }

        private void SetMessge(string info, int infoType = 0)
        {

            //info = DataHelper.DateFormat(DateTime.Now) + "" + info + "\n";

            info =  info + "\n";
            if (this.InvokeRequired)
            {
                // 如果需要跨线程调用,则使用 Invoke 方法
                this.Invoke(new Action(() =>
                {
                    rTB_Message.AppendText(info);
                    // 滚动文本框以使光标所在位置可见
                    //rTB_ResultInfo.ScrollToCaret();
                    // 选中插入点
                    rTB_Message.Focus();
                }));
            }
            else
            {
                // 如果在 UI 线程中,则直接更新控件
                rTB_Message.AppendText(info);
                // 滚动文本框以使光标所在位置可见
                //rTB_ResultInfo.ScrollToCaret();
                // 选中插入点
                rTB_Message.Focus();
            }
        }

        private void tool_bt_select_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                Application.DoEvents();
                filePath = ofd.FileName;
                var imagebyte = File.ReadAllBytes(filePath);
                bmp = new Bitmap(new MemoryStream(imagebyte));
                pictureBox1.Image = bmp;

                rTB_Message.Clear();

                if (bmp == null) return;

                stopwatch.Restart();
                OcrResult ocrResult = ocrEngin.Detect(filePath, padding, imgResize, boxScoreThresh, boxThresh, unClipRatio, doAngle, mostAngle);

                stopwatch.Stop();
                SetMessge(ocrResult.StrRes);

                SetMessge("------------------------------");
                //SetMessge(ocrResult.ToString());
                SetMessge($"--------------耗时: {stopwatch.ElapsedMilliseconds} 毫秒----------------");

                pictureBox2.Image = ocrResult.BoxImg.ToBitmap();
            }
        }

        private void tool_bt_screenshot_Click(object sender, EventArgs e)
        {
            this.Hide();
            System.Threading.Thread.Sleep(200);
            Application.DoEvents();
            ScreenCapturer.ScreenCapturerTool screenCapturer = new ScreenCapturer.ScreenCapturerTool();

            if (screenCapturer.ShowDialog() == DialogResult.OK)
            {
                bmp = (Bitmap)screenCapturer.Image;

                string newFiles = outPath+"\\" + DataHelper.GetTimestamp() + ".jpg";
                bmp.Save(newFiles, ImageFormat.Jpeg);

                pictureBox1.Image = bmp;

                try
                {
                    stopwatch.Restart();
                    OcrResult ocrResult = ocrEngin.Detect(newFiles, padding, imgResize, boxScoreThresh, boxThresh, unClipRatio, doAngle, mostAngle);

                    stopwatch.Stop();
                    SetMessge(ocrResult.StrRes);

                    SetMessge($"--------------耗时: {stopwatch.ElapsedMilliseconds} 毫秒----------------");
                    //SetMessge(ocrResult.ToString());

                    pictureBox2.Image = ocrResult.BoxImg.ToBitmap();
                }
                catch (Exception ex)
                {
                    SetMessge(ex.Message);
                }

            }
            this.Show();
        }

        private void tool_bt_PDF_Click(object sender, EventArgs e)
        {

            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "所有文件 (*.*)|*.*|PDF|*.pdf";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                string pdfPath = ofd.FileName;
                // 1. 解析PDF获取页面图像
                using (var document = PdfDocument.Load(pdfPath))
                {
                    string firstFiles = "";
                    stopwatch.Restart();
                    for (int pageIndex = 0; pageIndex < document.PageCount; pageIndex++)
                    {
                        // 渲染PDF页面为图像
                        using (var image = document.Render(pageIndex, 400, 800, false))
                        {
                            string newFiles = outPath + "\\" + DataHelper.GetTimestamp() + ".jpg";
                            if (pageIndex == 0)
                            {
                                firstFiles = newFiles;
                            }
                            image.Save(newFiles, ImageFormat.Jpeg);

                            OcrResult ocrResult = ocrEngin.Detect(newFiles, padding, imgResize, boxScoreThresh, boxThresh, unClipRatio, doAngle, mostAngle);

                            stopwatch.Stop();
                            SetMessge(ocrResult.StrRes);

                        }
                    }
                    if (firstFiles.Length > 0)
                    {
                        var imagebyte = File.ReadAllBytes(firstFiles);
                        pictureBox1.Image = new Bitmap(new MemoryStream(imagebyte));
                    }

                    //SetMessge(ocrResult.ToString());
                    SetMessge($"--------------耗时: {stopwatch.ElapsedMilliseconds} 毫秒----------------");
                }
            }

        }
    }
}

四、效果展示

C#之OCR识别

(图一为屏幕截图识别,图二为动车票信息识别)

五、资源下载

链接:https://download.csdn.net/download/weixin_42148410/90827048

相关推荐
mudtools9 小时前
.NET驾驭Word之力:玩转文本与格式
c#·.net
唐青枫13 小时前
C#.NET 数据库开发提速秘籍:SqlSugar 实战详解
c#·.net
mudtools1 天前
.NET驾驭Word之力:理解Word对象模型核心 (Application, Document, Range)
c#·.net
大飞pkz1 天前
【设计模式】C#反射实现抽象工厂模式
设计模式·c#·抽象工厂模式·c#反射·c#反射实现抽象工厂模式
唐青枫2 天前
从入门到进阶:C#.NET Stopwatch 计时与性能测量全攻略
c#·.net
paid槮2 天前
机器视觉之图像处理篇
图像处理·opencv·计算机视觉
未来之窗软件服务2 天前
幽冥大陆(二)RDIFSDK 接口文档:布草洗涤厂高效运营的技术桥梁C#—东方仙盟
开发语言·c#·rdif·仙盟创梦ide·东方仙盟
1uther2 天前
Unity核心概念⑨:Screen
开发语言·游戏·unity·c#·游戏引擎
阿幸软件杂货间2 天前
Office转PDF转换器v1.0.py
开发语言·pdf·c#
sali-tec2 天前
C# 基于halcon的视觉工作流-章34-环状测量
开发语言·图像处理·算法·计算机视觉·c#