初尝PaddleOCR识别图片中的文字

引言

  • 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;

            }
        }

    }
}

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

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术搬砖先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值