引言
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