初尝PaddleOCR识别图片中的文字

news2024/11/23 12:39:34

引言

  • PaddleOCR是一个基于飞桨深度学习框架的OCR工具包,它集成了丰富的文字检测、识别和后处理算法,能够高效、准确地识别出图片中的文字。

说明

  • OpenVINO.NET是一个由开源开发者sdcb发布的,一个个强大的工具集,通过优化神经网络和加速推理,帮助他们快速构建高性能的机器学习和计算机视觉应用。
  • PaddleOCR 旨在打造一套丰富、领先、且实用的 OCR 工具库,助力开发者训练出更好的模型,并应用落地。
 <Grid>
     <Grid.RowDefinitions>
         <RowDefinition Height="50"></RowDefinition>
         <RowDefinition></RowDefinition>
     </Grid.RowDefinitions>
     <Grid.ColumnDefinitions>
         <ColumnDefinition></ColumnDefinition>
         <ColumnDefinition></ColumnDefinition>
     </Grid.ColumnDefinitions>
     <!--添加两个按钮,分别设置打开图片和打开文本-->
     <Button Grid.Row="0" Grid.Column="0" x:Name="btnOpenImage" Content="打开图片" Background="Blue" Foreground="White" Width="100" Height="40" HorizontalAlignment="Right" VerticalAlignment="Center" Click="btnDialog_Click"/>
     <Button Grid.Row="0" Grid.Column="1"  x:Name="btnOcrTxt" Content="立即识别" Background="Green" Foreground="White" Width="100" Height="40" Margin="10,0" HorizontalAlignment="Left" VerticalAlignment="Center" Click="btnOrc_Click"/>

     <!--添加两个边框 显示默认显示,打开后显示对应效果-->
     <Border Grid.Row="1" Grid.Column="0" Margin="10,10"  BorderBrush="Gray" BorderThickness="1">
         <Image x:Name="myImage"  Stretch="Fill"></Image>
     </Border>

     <ScrollViewer Grid.Row="1" Grid.Column="1" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
         <Border  Margin="10,10"  BorderBrush="Gray" BorderThickness="1">
             <TextBlock x:Name="myText" TextWrapping="Wrap"  Margin="0,10,0,0"  FontSize="18" />
         </Border>
     </ScrollViewer>
  
 </Grid>
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : System.Windows.Window
{
    private  string ImagePath=string.Empty;
    private Bitmap ImageInfo =null;
    private string pattern = @"[\u4e00-\u9fa50-9a-zA-Z]+";
    public MainWindow()
    {
        InitializeComponent();
        Settings.GlobalModelDirectory = System.IO.Path.Combine("D:\\WpfOcrApp\\Models");

    }
    private void btnDialog_Click(object sender, RoutedEventArgs e)
    {
        Button btnUpload = (Button)sender;
        OpenFileDialog openFileDialog = new OpenFileDialog
        {
            Filter = "Image files (*.jpg;*.png;*.jpeg)|*.jpg;*.png;*.jpeg",
            Title = btnUpload.Name.Equals("btnOpenImage", StringComparison.OrdinalIgnoreCase) ? "选择图片" : "选择TXT文件"
        };
        bool? result = openFileDialog.ShowDialog();
        if (result == true)
        {
            string filePath = openFileDialog.FileName;
            ImagePath = filePath;
            if (!string.IsNullOrWhiteSpace(filePath))
            {
                using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                {
                    // 创建一个BitmapImage对象并设置其StreamSource为FileStream  
                    BitmapImage bitmapImage = new BitmapImage();
                    bitmapImage.BeginInit();
                    bitmapImage.StreamSource = stream;
                    bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                    bitmapImage.EndInit();
                    ImageInfo = new Bitmap(stream);
                    // 确保Stream在BitmapImage使用之后被关闭  
                    stream.Close();
                    // 将BitmapImage对象设置为Image控件的Source  
                    myImage.Source = bitmapImage;
                }

            }
        }
    }

    private void btnOrc_Click(object sender, RoutedEventArgs e)
    {
        if (string.IsNullOrWhiteSpace(ImagePath))
        {
            myText.Text = $"请先选择图片";
            return;
        }
       OrcResult();

    }

    private void OrcResult()
    {
       // 如何模型不存在,则会自动下载,如果wpf 出现下载不下来,可以把这段代码在控制台上执行下载
        FullOcrModel fullOcrModel = OnlineFullModels.ChineseServerV4.DownloadAsync().GetAwaiter().GetResult();
        Mat src = Cv2.ImRead(@$"{ImagePath}");
        // 注意 使用CUP 最好设置一下DetectionStaticSize和RecognitionStaticWidth这两个参数
        // GPU 默认就设置了
        using (PaddleOcrAll all = new(fullOcrModel, new PaddleOcrOptions(new Sdcb.OpenVINO.DeviceOptions("CPU")) 
        {
            DetectionStaticSize = new OpenCvSharp.Size(1024, 1024),
            RecognitionStaticWidth = 512
        })
        {
            AllowRotateDetection = true,
            Enable180Classification = true,
        })
        {
            StringBuilder builder = new StringBuilder();
            Stopwatch sw = Stopwatch.StartNew();
            PaddleOcrResult result = all.Run(src);
            builder.AppendLine($"总耗时:{sw.ElapsedMilliseconds} ms");
            string strText = result.Text;
            List<string> strings = strText.Split('\n').ToList();
            foreach (var item in strings)
            {
                bool isMatch = Regex.IsMatch(item, pattern);
                if (isMatch)
                    builder.AppendLine(item);
            }

            using (Graphics g = Graphics.FromImage(ImageInfo))
            {
                foreach (PaddleOcrResultRegion region in result.Regions)
                {
                    // 设置线条的样式(如颜色、粗细等)  
                    System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Brushes.Red, 2);
                    bool isMatch = Regex.IsMatch(region.Text, pattern);
                    if (isMatch)
                        g.DrawRectangle(pen, region.Rect.BoundingRect().Left, region.Rect.BoundingRect().Top, region.Rect.BoundingRect().Width, region.Rect.BoundingRect().Height);
                    //builder.AppendLine($"Text: {region.Text}, Score: {region.Score}, RectCenter: {region.Rect.Center}, RectSize:    {region.Rect.Size}, Angle: {region.Rect.Angle}");

                }
            }

            myText.Text = builder.ToString();
            using (MemoryStream memory = new MemoryStream())
            {
                ImageInfo.Save(memory, System.Drawing.Imaging.ImageFormat.Png);
                memory.Position = 0;
                // 创建一个BitmapImage对象并设置其StreamSource为FileStream  
                BitmapImage bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                bitmapImage.StreamSource = memory;
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.EndInit();
                // 确保Stream在BitmapImage使用之后被关闭  
                memory.Close();
                // 将BitmapImage对象设置为Image控件的Source  
                myImage.Source = bitmapImage;

            }
        }

    }
}

上述代码运行效果如下:
识别效果

参考

  • https://github.com/sdcb/OpenVINO.NET
  • https://github.com/paddlepaddle/PaddleOCR

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1894153.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高性价比模块:LSYT201B语音模块学习使用

最近打算做个语音的项目&#xff0c;找到了深圳雷龙发展的LSY201B这款语音模块&#xff0c;写出来安利一下 程序源码&#xff1a;SuiXinSc/Speech-Module (github.com) 或者进入Q群找我获取 目录 一&#xff0c;简要介绍&#xff1a; 硬件参数&#xff1a; 1&#xff0c;处理…

Spring MVC 中使用 RESTFul 编程风格

1. Spring MVC 中使用 RESTFul 编程风格 文章目录 1. Spring MVC 中使用 RESTFul 编程风格2. RESTFul 编程风格2.1 RESTFul 是什么2.2 RESTFul风格与传统方式对比 3. Spring MVC 中使用 RESTFul 编程风格(增删改查)的使用3.1 准备工作3.2 RESTFul 风格的 “查询” 所有&#xf…

Linux-页表如何对物理内存进行映射

1.1 页框和页帧 我们知道通过页表可以将虚拟内存映射到对应的物理内存&#xff0c;而操作系统对于物理内存的管理并不是以字节为单位的&#xff0c;而是将物理内存分为许多大小为4KB的块&#xff0c;称为页框或页帧&#xff0c;这就是为什么我们在创建共享内存是建议将大小设定…

2024年7月4日 (周四) 叶子游戏新闻

老板键工具来唤去: 它可以为常用程序自定义快捷键&#xff0c;实现一键唤起、一键隐藏的 Windows 工具&#xff0c;并且支持窗口动态绑定快捷键&#xff08;无需设置自动实现&#xff09;。 卸载工具 HiBitUninstaller: Windows上的软件卸载工具 《最终幻想14》画面升级后 著名…

YOLOv10全网最新创新点改进系列:融合GSConv+Slim Neck,双改进、双增强,替换特征融合层实现, 轻量化涨点改进策略,有效涨点神器!

YOLOv10全网最新创新点改进系列&#xff1a;融合GSConvSlim Neck&#xff0c;双改进、双增强&#xff0c;替换特征融合层实现&#xff0c; 轻量化涨点改进策略&#xff0c;有效涨点神器&#xff01; 所有改进代码均经过实验测试跑通&#xff01;截止发稿时YOLOv10已改进40&…

【刷题笔记(编程题)05】另类加法、走方格的方案数、井字棋、密码强度等级

1. 另类加法 给定两个int A和B。编写一个函数返回AB的值&#xff0c;但不得使用或其他算数运算符。 测试样例&#xff1a; 1,2 返回&#xff1a;3 示例 1 输入 输出 思路1: 二进制0101和1101的相加 0 1 0 1 1 1 0 1 其实就是 不带进位的结果1000 和进位产生的1010相加 无进位加…

H5实现第三方分享功能,(WhatsApp,Facebook,Messenger,Instagram,Telegram,Zalo,Twitter/X)

1. H5实现第三方分享功能 1. WhatsApp 分享 https://api.whatsapp.com/send/?phone&app_absent0&text${codeUrl}2. Facebook 分享 https://www.facebook.com/sharer/sharer.php?u${codeUrl}3. Messenger 分享 https://www.messenger.com/?${codeUrl}4. Instagra…

​​服务拆分的原则

目录 一、单一职责原则 二、服务自治原则 三、单向依赖 一、单一职责原则 单⼀职责原则原本是面向对象设计中的⼀个基本原则, 它指的是⼀个类应该专注于单⼀功能. 不要存在多于⼀个导致类变更的原因 在微服务架构中, ⼀个微服务也应该只负责⼀个功能或业务领域, 每个服务应该…

代码随想录算法训练营第70天图论9[1]

代码随想录算法训练营第70天:图论9 ‍ 拓扑排序精讲 卡码网&#xff1a;117. 软件构建(opens new window) 题目描述&#xff1a; 某个大型软件项目的构建系统拥有 N 个文件&#xff0c;文件编号从 0 到 N - 1&#xff0c;在这些文件中&#xff0c;某些文件依赖于其他文件的…

html+css+js淘宝商品界面

点击商品&#xff0c;alert弹出商品ID 图片使用了占位符图片&#xff0c;加载可能会慢一点 你可以把它换成自己的图片&#x1f603;源代码在图片后面 效果图 源代码 <!DOCTYPE html> <html lang"zh"> <head> <meta charset"UTF-8"…

嵌入式底层系统了解

当裸机功能不复杂的时候&#xff0c;即类似与点亮一个LED灯&#xff0c;驱动LCD和OLED这样的模块&#xff0c;以及各位大学生的搭积木式的毕业设计(狗头保命&#xff09;&#xff0c;此时可以简单地分为硬件和软件层&#xff08;应用层),以及以中间层作为中间联系。 当需要实现…

代码随想录算法训练营第2天|LeetCode977,209,59

977.有序数组平方 题目链接&#xff1a; 977. 有序数组的平方 - 力扣&#xff08;LeetCode&#xff09; 文章讲解&#xff1a;代码随想录 视频讲解&#xff1a; 双指针法经典题目 | LeetCode&#xff1a;977.有序数组的平方_哔哩哔哩_bilibili 第一想法 暴力算法肯定是先将元素…

docker的安装与基本使用

一.docker的安装卸载 1.先安装所需软件包 yum install -y yum-utils2.设置stable镜像仓库 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 3.安装DOCKER CE yum -y install docker-ce docker-ce-cli containerd.io 4.验…

【unity实战】使用Unity实现动作游戏的攻击 连击 轻重攻击和打击感

最终效果 文章目录 最终效果前言素材下载&#xff1a;玩家移动跳跃控制攻击动画配置轻攻击重攻击 攻击时禁止移动和攻击移动补偿敌人击退和播放受击动画受击特效攻击停顿和屏幕震动局部顿帧&#xff08;补充&#xff09;参考源码完结 前言 注意本文为自己的学习记录笔记&#…

微机原理 选择题

D C MOV、PUSH、POP、XLAT&#xff08;查表&#xff09;、IN、OUT不影响标志位 D B D C D C D B 1. (单选题, 5分)8位无符号数(字节)表示的数值范围是( ), 16位无符号数(字)表示的数值范围是( )。 A. 0~128 0~32768B. 0~255 0~655…

Websocket通信实战项目(js)(图片互传应用)(下)客户端H5+css+js实现

Rqtz : 个人主页 ​ 共享IT之美&#xff0c;共创机器未来 Sharing the Beauty of IT and Creating the Future of Machines Together 目录 起始 客户端GUI Javascripts连接websocket 使用localStorage保存用户输入的IP Websocket连接成功 Websocket接收数据 解析…

51-5 权限维持2 - 影子账号(隐藏用户)

权限维持技术 权限维持技术(Persistence,也称为权限持久化)是一种能够在系统重启、用户更改密码或其他可能导致访问中断的情况下保持对系统访问的技术。例如,它包括创建系统服务、利用计划任务、修改系统启动项或注册表、以及映像劫持等方法。 创建影子账户 影子账户是指隐…

Labview_Workers5.0 学习笔记

1.Local Request 个人理解该类型的请求针对自身的&#xff0c;由EHL或者MHL到该vi的MHL中。 使用快速放置快捷键"Ctrl9"创建方法如下&#xff1a; 创建后的API接口命名均为rql开头&#xff0c;并且在所选main.vi中的MHL创建对应的条件分支。 此时使用该API函数就…

【计算机毕业设计】026基于微信小程序的原创音乐

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…