记得前面(忘了是哪天写的,反正是前些天,请用力点击这里观看)老周讲了一个14393新增的控件,可以很轻松地结合InkCanvas来完成涂鸦。其实,InkCanvas除了涂鸦外,另一个大用途是墨迹识别,就是手写识别。

识别功能早在Win 8 App的API中就有了,到了UWP,同样使用,这叫传承,一路学过来,都是一个体系的,我不明白为什么某些人一遇到升级就说SDK变化太大,适应不了。我是不明白了,有什么适应不了的,该不会是你笨吧,或者学习方法不对。反正老周在以前的博客中都说过了,学习要学活,不要把知识学死了,把东西往死里学,就是古人所说的书呆子。

好了,不谈论书呆子的事了,因为“书呆子”在民间有太多的误解,咱们还是说正题。

处理数字墨迹有两种方式:

1、一种是脱离InkCanvas控件的方法,处理过程是面向笔触(Stroke)的,这就需要你手动去管理好你的墨迹数据了;

2、要是上一种方法太麻烦,与InkCanvas关联的做法较好,这样不用自己去搞UI部分的内容。

本着易用、久用、耐用、实用、妙用等伟大原则,我们实现手写识别还是不要脱离InkCanvas控件,这样的话实现起来会轻松很多,除非你要搞很高级的应用场景。

不讲过多的理论,免得大家看的头晕,老周简单说一个原理,大家懂了原理后,直接干活,这是学编程的万能招数。

先看看大致的步骤:

1、大家知道,InkCanvas有个关联的InkPresenter属性,引用的是InkPresenter实例,这个你得知道,不然后面的步骤就无法玩了。

2、InkPresenter类有个StrokeContainer属性,类型为InkStrokeContainer,它表示墨迹笔触的集合,被收集到的输入数据就存放到这个集合中。一个笔触通常是指你用笔/手指/鼠标按下时开始,直到你释放笔/手指/鼠标这一阶段中,所绘制出来的一段墨迹(从下笔到提笔)。一花一世界,一落一起一笔触。

3、实例化InkRecognizerContainer类,调用RecognizeAsync方法执行识别,上面为啥要提到InkStrokeContainer呢?因为执行识别需要它,你想啊,没有用户输入的墨迹(笔触)数据,一片空白,你识别个球。

4、识别后返回一个InkRecognitionResult列表,对于中文,通常只有一个InkRecognitionResult对象,但对于英文单词,可能会多个,一个InkRecognitionResult表示一个单词。对于一个InkRecognitionResult来说,访问GetTextCandidates方法返回一个字符串列表,即候选项,匹配度高的字符串排在前面。

5、也可以访问InkRecognizerContainer.GetRecognizers方法获取当前系统中已安装的语言识别引擎,中文系统至少会有一个简体中文的识别引擎。你可以到系统设置里面安装其他语言的引擎。

OK,基本思路有了,下面就可以做事情了。

首先,布置一下UI,XAML代码如下:

        <Grid Margin="15"><Grid.RowDefinitions><RowDefinition Height="auto"/><RowDefinition Height="300"/><RowDefinition Height="*"/></Grid.RowDefinitions><ComboBox Name="cmbRecons" Header="选一个:" DisplayMemberPath="Name"/><Border Background="LightGray" Grid.Row="1" Margin="2,6"><InkCanvas Name="inkcv" /></Border><TextBlock Grid.Row="2" Name="tbresult" TextWrapping="Wrap" Foreground="Red" FontSize="24"/></Grid>

ComboBox控件用来显示当前系统中安装的手写识别引擎,TextBlock用来显示识别结果。

现在,切换到代码视图,首先在页面类级别声明一个InkRecognizerContainer变量,并且实例化。

        InkRecognizerContainer inkRecognContainer = new InkRecognizerContainer();

另外,还需要一个Timer,作用是在墨迹收集2秒钟后进行识别。

        DispatcherTimer timer = new DispatcherTimer();……// 准备计时器// 延迟2秒,应该不算慢吧timer.Interval = TimeSpan.FromSeconds(2d);timer.Tick += onTimerTick;// 处理ink操作事件inkcv.InkPresenter.StrokeInput.StrokeStarted += (k1, k2) =>{// 人家正要下笔呢,没有在此时识别的道理
                timer.Stop();};inkcv.InkPresenter.StrokesCollected += (t1, t2) =>{// 墨迹已收集,可以进行识别
                timer.Start();};

当下笔开始书写时,会发生StrokeStarted事件,在此时,应该停止计时,你总不能人家一边写你就一边识别,没什么意思。但InkCanvas收集到输入笔触后,会发生StrokesCollected事件,这时候就可以开始计时了,2秒钟后进行识别。说白了就是在用户停止手写2秒钟后识别。

在ComboBox控件中显示系统已安装的识别引擎:

            // 获取已安装的识别引擎列表var inkrecogs = inkRecognContainer.GetRecognizers();// 将这些列表显示到ComboBox控件中cmbRecons.ItemsSource = inkrecogs;// 处理选项更改事件cmbRecons.SelectionChanged += (s1, s2) =>{// 将选中的识别引擎设为默认InkRecognizer currec = (InkRecognizer)cmbRecons.SelectedItem;inkRecognContainer.SetDefaultRecognizer(currec);};if (cmbRecons.Items.Count > 0)cmbRecons.SelectedIndex = 0;

当ComboBox控件做出选择后,引发SelectionChanged事件,在事件处理代码中可以调用SetDefaultRecognizer方法设置默认的识别引擎。

还有一件事,不要忘了,让InkCanvas支持笔、手触、鼠标来书写。

            // 全能书写inkcv.InkPresenter.InputDeviceTypes = Windows.UI.Core.CoreInputDeviceTypes.Mouse | Windows.UI.Core.CoreInputDeviceTypes.Touch | Windows.UI.Core.CoreInputDeviceTypes.Pen;

下面是核心代码,就是上面那个Timer的Tick事件处理,在处理代码中,执行手写识别,并显示识别的结果。

            // 如果InkStrokeContainer中没有收集笔触,那就没有识别的必要了// 所以Count应大于0if (inkcv.InkPresenter.StrokeContainer.GetStrokes().Count > 0){IReadOnlyList<InkRecognitionResult> results = await inkRecognContainer.RecognizeAsync(inkcv.InkPresenter.StrokeContainer, InkRecognitionTarget.All);// 处理结果if (results.Count > 0){StringBuilder strbd = new StringBuilder();strbd.AppendLine("结果:");// 每个InkRecognitionResult实例表示一个汉字/单词的识别结果// 而单个结果中又包含候选列表,最接近的识别结果优先级更高for(int x = 0; x < results.Count; x++){string s = string.Join(",", results[x].GetTextCandidates().ToArray());strbd.AppendLine(s);}// 显示结果tbresult.Text = strbd.ToString();// 清理墨迹
                    inkcv.InkPresenter.StrokeContainer.Clear();}}

不是很复杂,代码你应该看得懂的,不然,学.NET这么多年,太对不起自己了。注意的是,识别后返回多个结果,对于中文,通常只返回一个,因为多个汉字是可以一起识别,并放到字符候选列表中。

在代码的最后面有这么一句:

 inkcv.InkPresenter.StrokeContainer.Clear();

这句代码的作用是清除所收集的所有墨迹,清除后,InkCanvas会变回空白。

运行一下程序,然后手写一些字,看看识别效果。

示例源代码下载

【Win 10 应用开发】手写识别相关推荐

  1. AI应用开发实战 - 手写识别应用入门

    AI应用开发实战 - 手写识别应用入门 手写体识别的应用已经非常流行了,如输入法,图片中的文字识别等.但对于大多数开发人员来说,如何实现这样的一个应用,还是会感觉无从下手.本文从简单的MNIST训练出 ...

  2. 实验5-9 使用函数输出水仙花数_正点原子STM32F407探索者开发板资料连载第五十三章 手写识别实验

    1)实验平台:alientek 阿波罗 STM32F767 开发板 2)摘自<STM32F7 开发指南(HAL 库版)>关注官方微信号公众号,获取更多资料:正点原子 第五十三章 手写识别实 ...

  3. application.properties 不识别_阿波罗 STM32F767 开发板资料连载第五十八章 手写识别实验

    1)实验平台:alientek 阿波罗 STM32F767 开发板2)摘自<STM32F7 开发指南(HAL 库版)>关注官方微信号公众号,获取更多资料:正点原子 第五十八章 手写识别实验 ...

  4. 【正点原子STM32连载】第五十四章 手写识别实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1

    1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...

  5. Qt之手写识别开发笔记:Zinnia介绍、编译、使用以及Demo

    若该文为原创文章,未经允许不得转载 原博主博客地址:https://blog.csdn.net/qq21497936 原博主博客导航:https://blog.csdn.net/qq21497936/ ...

  6. python简单代码演示效果-10分钟教你用python 30行代码搞定简单手写识别!

    欲直接下载代码文件,关注我们的公众号哦!查看历史消息即可! 手写笔记还是电子笔记好呢? 毕业季刚结束,眼瞅着2018级小萌新马上就要来了,老腊肉小编为了咱学弟学妹们的学习,绞尽脑汁准备编一套大学秘籍, ...

  7. AI应用开发实战系列之三:手写识别应用入门

    AI应用开发实战 - 手写识别应用入门 手写体识别的应用已经非常流行了,如输入法,图片中的文字识别等.但对于大多数开发人员来说,如何实现这样的一个应用,还是会感觉无从下手.本文从简单的MNIST训练出 ...

  8. pc手写识别_如何在Windows 10 PC上改善手写识别

    pc手写识别 Windows 10 lets you use handwriting input in any application, and many applications include f ...

  9. 基于stm32f429的手写识别_【连载】STM32开发指南--第五十一章 手写识别实验

    最后将这64维特征分别与模板中的特征进行求距离运算.得到最小的距离为该输入的最佳识别结果输出. 关于手写识别原理,我们就介绍到这里.如果想自己实现手写识别,那得花很多时间学习和研究,但是如果只是应用的 ...

  10. cnn神经网络可以用于数据拟合吗_使用Keras搭建卷积神经网络进行手写识别的入门(包含代码解读)...

    本文是发在Medium上的一篇博客:<Handwritten Equation Solver using Convolutional Neural Network>.本文是原文的翻译.这篇 ...

最新文章

  1. java 配置微信js sdk_解析微信JS-SDK配置授权,实现分享接口
  2. 关于项目重构,知道真相的程序员眼泪笑了出来
  3. c/c++比较灵活的方法:回调函数和函数指针
  4. c 编程 mysql结果集_使用mysql C语言API编写程序—MYSQL数据库查询操作(执行查询操作,获取查询结果的字段数,记录行数,...
  5. H264 CAVLC 研究
  6. android 双线程等待,在Java/Android中启动另一个线程之前如何等待线程完成?
  7. MySQL左关联、右关联、内关联查询
  8. 深入理解Spring之九:DispatcherServlet初始化源码分析
  9. 结合实例学习F#(二) --基本数据类型Discriminated Unions
  10. macOS下JetBrains配置修改错误导致无法启动解决方案
  11. Spring.Net学习笔记(二)-数据访问器
  12. Android WebView中软键盘会遮挡输入框相关问题
  13. Oracle高级教程
  14. 实验二 OpenGL的简单动画
  15. k8s高可用二进制部署
  16. ubuntu为jar创建快捷方式
  17. 腾讯私有云TStack 自动化部署
  18. 树莓派 4b 配置 USB 网络连接
  19. 鸡兔同笼问题。上有头30个,下有脚90只,问鸡兔各有多少只。
  20. 搜狗拼音输入法输入数字和英文时总是有空格

热门文章

  1. oracle pl/sql 无监听程序
  2. MSP430学习笔记10-ADC采集1602显示
  3. JS之形参带默认值的写法代码
  4. 数据库存储 层次、树形结构 的标准做法
  5. 在 ASP.NET MVC Web 应用程序中输出 RSS Feeds
  6. 一个三层结构的留言板,结合了ajax效果
  7. ADO.NET数据访问模式
  8. Docker使用(三)使用Dockerfile创建镜像以及为镜像添加SSH服务
  9. JavaScript 邮件正则练习
  10. 现代软件工程第一次结对编程(黄金点游戏)总结