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

相关推荐
ACQTEC研索仪器1 小时前
案例分享--汽车制动卡钳DIC测量
图像处理·汽车·dic·数字图像相关·vic-3d非接触全场应变测量
lljss20205 小时前
C# 一个解决方案放一个dll项目,一个dll测试项目 ,调试dll项目的源码
c#
沉到海底去吧Go5 小时前
【图片识别改名】如何批量将图片按图片上文字重命名?自动批量识别图片文字并命名,基于图片文字内容改名,WPF和京东ocr识别的解决方案
ocr·wpf·图片识别改名·图片识别重命名·图片内容改名
KerwinChou_CN6 小时前
自由开发者计划 004:创建一个苹果手机长截屏小程序
图像处理·算法·智能手机·小程序
ghost14313 小时前
C#学习第27天:时间和日期的处理
开发语言·学习·c#
jason成都13 小时前
c#压缩与解压缩-SharpCompress
开发语言·c#
傻啦嘿哟14 小时前
从零开始:用Tkinter打造你的第一个Python桌面应用
开发语言·c#
CodeCraft Studio15 小时前
PDF处理控件Aspose.PDF教程:在 C# 中更改 PDF 页面大小
前端·pdf·c#
InCerry16 小时前
.NET周刊【5月第4期 2025-05-25】
c#·.net·.net周刊
阿蒙Amon19 小时前
C#获取磁盘容量:代码实现与应用场景解析
开发语言·c#