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

相关推荐
Dfreedom.13 分钟前
开运算与闭运算:图像形态学中的“清道夫”与“修复匠”
图像处理·python·opencv·开运算·闭运算
AomanHao1 小时前
【ISP】图像质量评价指标-通透度
图像处理·通透度·评价标准
wgfhill2 小时前
【亲测可用】照片相似度检测删除一键清理重复图片!智能相似度检测工具,释放海量存储空间
图像处理
MyBFuture3 小时前
C#数组详解:一维二维与交错数组
开发语言·windows·c#·visual studio·vision pro
有来技术4 小时前
ASP.NET Core 权限管理系统(RBAC)设计与实现|vue3-element-admin .NET 后端
vue.js·后端·c#·asp.net·.net
sali-tec4 小时前
C# 基于OpenCv的视觉工作流-章20-仿射变换
图像处理·人工智能·opencv·算法·计算机视觉
沃达德软件5 小时前
视频侦查图像清晰化技术
图像处理·人工智能·目标检测·机器学习·计算机视觉·视觉检测·超分辨率重建
张人玉5 小时前
C#WinFrom中show和ShowDialog的区别
开发语言·microsoft·c#
m0_748233175 小时前
C#:微软的现代编程利器
开发语言·microsoft·c#
Traced back6 小时前
SQL Server数据自动清理系统最终版(C# WinForms完整源码)
数据库·c#·.net