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

相关推荐
翔云 OCR API2 小时前
发票查验接口详细接收参数说明-C#语言集成完整示例-API高效财税管理方案
开发语言·c#
虫小宝3 小时前
高佣金的返利平台性能压测:从单接口到全链路的性能瓶颈分析
c#·linq
故事不长丨3 小时前
C#集合:解锁高效数据管理的秘密武器
开发语言·windows·c#·wpf·集合·winfrom·字典
MF_AI5 小时前
大型烟雾火灾检测识别数据集:25w+图像,2类,yolo标注
图像处理·人工智能·深度学习·yolo·计算机视觉
jghhh015 小时前
基于C#实现与三菱FX系列PLC串口通信
开发语言·算法·c#·信息与通信
故事不长丨5 小时前
C#队列深度剖析:解锁高效编程的FIFO密码
visualstudio·c#·wpf·多线程·winfrom·队列·queue
bugcome_com6 小时前
C# 反射(Reflection)超全解析
c#
皮肤科大白8 小时前
图像处理的 Python库
图像处理·人工智能·python
weixin_377634848 小时前
【开源-细粒度图像识别】SCAN快慢思考 无需微调标注即可分类
图像识别·图像分类
bjzhang758 小时前
Dorisoy.AMS--一款采用C# WinForm框架+SQLite数据库的企业/机构资产管理解决方案
sqlite·c#·资产管理