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

相关推荐
kaikaile199538 分钟前
基于C#实现一维码和二维码打印程序
开发语言·c#
我不是程序猿儿1 小时前
【C#】画图控件的FormsPlot中的Refresh功能调用消耗时间不一致缘由
开发语言·c#
rit84324991 小时前
C# Socket 聊天室(含文件传输)
服务器·开发语言·c#
棒棒的皮皮2 小时前
【OpenCV】Python图像处理几何变换之翻转
图像处理·python·opencv·计算机视觉
Coding茶水间6 小时前
基于深度学习的水果检测系统演示与介绍(YOLOv12/v11/v8/v5模型+Pyqt5界面+训练代码+数据集)
图像处理·人工智能·深度学习·yolo·目标检测·机器学习·计算机视觉
白衣衬衫 两袖清风6 小时前
ABP框架+Dapper执行原生sql
sql·c#·.net
在路上看风景7 小时前
1.15 并行编程
c#
chao1898447 小时前
基于C# WinForm实现的仿微信打飞机游戏
游戏·微信·c#
张人玉7 小时前
图像处理函数与形态学操作笔记(含 Halcon 示例)
图像处理·人工智能·笔记·halcon
wearegogog1238 小时前
C# 条码打印程序(一维码 + 二维码)
java·开发语言·c#