首页 > 编程语言 >C# 手写识别方案整理

C# 手写识别方案整理

时间:2023-07-14 22:34:04浏览次数:42  
标签:C# strokes Windows Ink var new 手写 识别

书写识别,网上的大佬们都有输出。

书写识别存在的2个问题:

  1. 直接拿官网的案例(将 Windows Ink 笔划识别为文本和形状 - Windows apps | Microsoft Learn),会发现输出准确度不高。
  2. 另外如果书写过快,词组识别也是个问题,毕竟无法准确分割字之间的笔迹。

我结合之前开发经验,整理下书写识别比较完善的方案。

单个字的识别方案

复制代码
 1     private List<string> Recognize(StrokeCollection strokes)
 2     {
 3         if (strokes == null || strokes.Count == 0)
 4             return null;
 5         // 创建识别器
 6         var recognizers = new Recognizers();
 7         var chineseRecognizer = recognizers.GetDefaultRecognizer(0x0804);
 8         using var recContext = chineseRecognizer.CreateRecognizerContext();
 9         // 根据StrokeCollection构造 Ink 类型的笔迹数据。
10         using var stream = new MemoryStream();
11         strokes.Save(stream);
12         using var inkStorage = new Ink();
13         inkStorage.Load(stream.ToArray());
14         using var inkStrokes = inkStorage.Strokes;
15         //设置笔画数据
16         using (recContext.Strokes = inkStrokes)
17         {
18             //识别笔画数据
19             var recognitionResult = recContext.Recognize(out var statusResult);
20             // 如果识别过程中出现问题,则返回null
21             return statusResult == RecognitionStatus.NoError ?
22                 recognitionResult.GetAlternatesFromSelection().OfType<RecognitionAlternate>().Select(i => i.ToString()).ToList() :
23                 null;
24         }
25     }
复制代码

这里单字识别,想要提高识别率,可以将stroke合并成一个:

复制代码
1     var points = new StylusPointCollection();
2     foreach (var stroke in strokes)
3     {
4         points.Add(new StylusPointCollection(stroke.StylusPoints));
5     }
6     var newStroke = new StrokeCollection
7     {
8         new Stroke(points)
9     };
复制代码

多字的识别方案

复制代码
 1     public IEnumerable<string> Recognize(StrokeCollection strokes)
 2     {
 3         if (strokes == null || strokes.Count == 0)
 4             return null;
 5 
 6         using var analyzer = new InkAnalyzer();
 7         analyzer.AddStrokes(strokes,0x0804);
 8         analyzer.SetStrokesType(strokes, StrokeType.Writing);
 9         var status = analyzer.Analyze();
10         if (status.Successful)
11         {
12             var alternateCollection = analyzer.GetAlternates();
13             return alternateCollection.OfType<AnalysisAlternate>().Select(x => x.RecognizedString);
14         }
15         return null;
16     }
复制代码

看下效果图

环境及DLL引用

引用的命名空间是:Windows.Ink和MicroSoft.Ink,需要引用的DLL文件有四个。可点击下载:InkRecognizeDependencies.rar

  • IACore.dll、IALoader.dll、IAWinFX.dll,这三个DLL文件都是Intel集成显卡驱动的重要组成部分,包含了图形处理模块,尤其是IAWinFX为WPF应用提供了支持硬件加速的图形渲染。
  • Microsoft.Ink.dll

值得说明一下,Windows.Ink与Microsoft.Ink在平台支持上不同,如果有要适配不同版本的windows,需要去上方代码修改下

  • Microsoft.Ink支持Windows XP、Vista 和 Win7 等旧版 Windows,兼容性高。但Win10及以上版本,官方推荐使用Windows.Ink

  • Windows.Ink,则仅支持Win8以上版本

引用了上面4个DLL文件后,还有2个环境问题:

  • 在App.config文件中,对节点startup添加属性 useLegacyV2RuntimeActivationPolicy="true"
  • 修改项目配置为x86

环境遇到问题,也可以参考这篇博客 【WPF】提高InkAnalyer手写汉字识别的准确率 - 大佛脚下 - 博客园 (cnblogs.com)

 

参考博客列表:

C# vs2012 如何实现手写识别?快来看看吧~_手写识别控件_想吃米豆腐的博客-CSDN博客

C# 实现手写输入功能_zls365365的博客-CSDN博客

【WPF】提高InkAnalyer手写汉字识别的准确率 - 大佛脚下 - 博客园 (cnblogs.com)

标签:C#,strokes,Windows,Ink,var,new,手写,识别
From: https://www.cnblogs.com/Leo_wl/p/17555151.html

相关文章

  • Lync/Skype用户无法共享PPT(一)
    故障背景最近在做Lync2013升级到SkypeforBusiness2019项目,遇到了一个无法共享PPT的问题。旧有环境为Lync2013+旧OWA服务器,在将新的SFB2019池搭建好后,环境处于Lync2013+SFB2019+旧OWA的共存场景。此时位于旧池中的用户共享功能正常,但是位于新SFB2019前端池的用户,无法共享PPT,提示如......
  • Elasticsearch:使用 runtime fields 探索你的数据
    Elasticsearch考虑要提取字段的大量日志数据。为数据建立索引非常耗时,并且会占用大量磁盘空间,而你只想探索数据结构而无需预先提交schema。你知道你的日志数据包含你要提取的特定字段。在这种情况下,我们要关注@timestamp和消息字段。通过使用运行时字段(runtimefields),你可以......
  • Java Comparator接口的介绍与使用
    JavaComparator接口的介绍与使用什么是Comparator接口?Comparator接口是一个用于比较两个对象大小的接口,它定义了一个抽象方法compare(To1,To2),根据o1和o2的大小返回一个整数值。Comparator接口位于java.util包中,它是一个泛型接口,可以指定比较的对象类型。Comparator接口的......
  • Grpc C++使用总结
    Grpc一,安装安装依赖sudoapt-getinstallpkg-configsudoapt-getinstallautoconfautomakelibtoolmakeg++unzipsudoapt-getinstalllibgfalgs-devlibgtest-devsudoapt-getinstallclanglibc++-dev下载gRPCgitclonehttps://github.com/grpc/grpc.gitc......
  • c++ day 9
    今天来学习选择排序选择排序有多种方法下面是方法一:选择排序(SelectionSort)是一种简单但低效的排序算法。它的基本思想是在未排序的部分中选择最小(或最大)的元素,并将其放置在已排序部分的末尾。通过重复这个过程,直到所有元素都排好序为止。下面是选择排序的C++实现示例:#incl......
  • 【渗透测试】利用Cobalt Strike渗透Windows
    目标在kali中使用CobaltStrike对Windows进行渗透机器环境kali(服务端):192.168.175.129win11(攻击机):192.168.175.128win11(靶机):192.168.175.137步骤一、安装CobaltStrike将压缩包解压unrarx./CobaltStrike4_8_lusuo.rar进入解压后的Server文件夹,赋予文件执行......
  • c# PasswordBoxHelper
    1publicclassPasswordBoxHelper2{3publicstaticreadonlyDependencyPropertyPasswordProperty=DependencyProperty.RegisterAttached("Password",typeof(string),typeof(PasswordBoxHelper),4newPropertyMetadata(......
  • 运动控制-达妙C#开源USB2CAN例程
    C#Can总线资料不多,达妙USB2CAN入口http://www.dmbot.cn/forum.php?mod=viewthread&tid=328&extra=page%3D1......
  • [已过万次测试] MIT 6.5840 2023 Lab 4 Shard KV Server TaskA, TaskB, Challenge 通
    MIT6.58402023Lab4ShardKVServerTaskA,TaskB,Challenge前言这波是终于写完了MIT6.5840的所有lab了。lab均是独立完成,没有任何参考,哈哈,还是挺有成就感的。lab4其实在上周就已经写完了,不过比较懒,拖了一周才开始写总结。本次lab4,在所有lab中,个人认为难度仅次于lab2,也......
  • 2023-07-14:讲一讲Kafka与RocketMQ中存储设计的异同?
    2023-07-14:讲一讲Kafka与RocketMQ中存储设计的异同?答案2023-07-14:在Kafka中,文件的布局采用了Topic/Partition的方式,每个分区对应一个物理文件夹,且在分区文件级别上实现了顺序写入。然而,当一个Kafka集群拥有大量的主题和每个主题拥有数百个分区时,在高并发写入消息的情况下,IO操作......