【Win 10 应用开发】手写识别
记得前面(忘了是哪天写的,反正是前些天,请用力点击这里观看)老周讲了一个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 > )
cmbRecons.SelectedIndex = ;
当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应大于0
if (inkcv.InkPresenter.StrokeContainer.GetStrokes().Count > )
{
IReadOnlyList<InkRecognitionResult> results = await inkRecognContainer.RecognizeAsync(inkcv.InkPresenter.StrokeContainer, InkRecognitionTarget.All);
// 处理结果
if (results.Count > )
{
StringBuilder strbd = new StringBuilder();
strbd.AppendLine("结果:");
// 每个InkRecognitionResult实例表示一个汉字/单词的识别结果
// 而单个结果中又包含候选列表,最接近的识别结果优先级更高
for(int x = ; 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 应用开发】手写识别的更多相关文章
- AI应用开发实战 - 手写识别应用入门
AI应用开发实战 - 手写识别应用入门 手写体识别的应用已经非常流行了,如输入法,图片中的文字识别等.但对于大多数开发人员来说,如何实现这样的一个应用,还是会感觉无从下手.本文从简单的MNIST训练出 ...
- 10分钟搞懂Tensorflow 逻辑回归实现手写识别
1. Tensorflow 逻辑回归实现手写识别 1.1. 逻辑回归原理 1.1.1. 逻辑回归 1.1.2. 损失函数 1.2. 实例:手写识别系统 1.1. 逻辑回归原理 1.1.1. 逻辑回归 ...
- 背水一战 Windows 10 (62) - 控件(媒体类): InkCanvas 保存和加载, 手写识别
[源码下载] 背水一战 Windows 10 (62) - 控件(媒体类): InkCanvas 保存和加载, 手写识别 作者:webabcd 介绍背水一战 Windows 10 之 控件(媒体类) ...
- 10分钟教你用python 30行代码搞定简单手写识别!
欲直接下载代码文件,关注我们的公众号哦!查看历史消息即可! 手写笔记还是电子笔记好呢? 毕业季刚结束,眼瞅着2018级小萌新马上就要来了,老腊肉小编为了咱学弟学妹们的学习,绞尽脑汁准备编一套大学秘籍, ...
- win10下通过Anaconda安装TensorFlow-GPU1.3版本,并配置pycharm运行Mnist手写识别程序
折腾了一天半终于装好了win10下的TensorFlow-GPU版,在这里做个记录. 准备安装包: visual studio 2015: Anaconda3-4.2.0-Windows-x86_64 ...
- Tensorflow之基于MNIST手写识别的入门介绍
Tensorflow是当下AI热潮下,最为受欢迎的开源框架.无论是从Github上的fork数量还是star数量,还是从支持的语音,开发资料,社区活跃度等多方面,他当之为superstar. 在前面介 ...
- 使用PyTorch构建神经网络模型进行手写识别
使用PyTorch构建神经网络模型进行手写识别 PyTorch是一种基于Torch库的开源机器学习库,应用于计算机视觉和自然语言处理等应用,本章内容将从安装以及通过Torch构建基础的神经网络,计算梯 ...
- (手写识别) Zinnia库及其实现方法研究
Zinnia库及其实现方法研究 (转) zinnia是一个开源的手写识别库.采用C++实现.具有手写识别,学习以及文字模型数据制作转换等功能. 项目地址 [http://zinnia.sourcefo ...
- TensorFlow 入门之手写识别(MNIST) softmax算法
TensorFlow 入门之手写识别(MNIST) softmax算法 MNIST flyu6 softmax回归 softmax回归算法 TensorFlow实现softmax softmax回归算 ...
随机推荐
- 移动端之Android开发的几种方式的初步体验
目前越来越多的移动端混合开发方式,下面列举的大多数我都略微的尝试过,就初步的认识写个简单的心得: 开发方式 开发环境 是否需要AndroidSDK 支持跨平台 开发语言&技能 MUI Win+ ...
- Paypal开发中遇到请求被中止: 未能创建 SSL/TLS 安全通道及解决方案
最近在基于ASP.NET上开发了Paypal支付平台,在ASP.NET开发的过程中没有遇到这个问题,但是引用到MVC开发模式中的时候就出现了"未能创建 SSL/TLS 安全通道及解决方案&q ...
- 免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)
前面介绍了六种.NET组件,其中有一种组件是写文件的压缩和解压,现在介绍另一种文件的解压缩组件SharpZipLib.在这个组件介绍系列中,只为简单的介绍组件的背景和简单的应用,读者在阅读时可以结合官 ...
- WebApi基于Token和签名的验证
最近一段时间在学习WebApi,涉及到验证部分的一些知识觉得自己并不是太懂,所以来博客园看了几篇博文,发现一篇讲的特别好的,读了几遍茅塞顿开(都闪开,我要装逼了),刚开始读有些地方不理解,所以想了很久 ...
- C# 用SoapUI调试WCF服务接口(WCF中包含用户名密码的验证)
问题描述: 一般调试wcf程序可以直接建一个单元测试,直接调接口. 但是,这次,我还要测试在接口内的代码中看接收到的用户名密码是否正确,所以,单一的直接调用接口方法行不通, 然后就想办法通过soapU ...
- SpringMVC+Shiro权限管理【转】
1.权限的简单描述 2.实例表结构及内容及POJO 3.Shiro-pom.xml 4.Shiro-web.xml 5.Shiro-MyShiro-权限认证,登录认证层 6.Shiro-applica ...
- window7系统怎么找到开始运行命令
右击开始->属性->开始菜单->自定义>点击运行命令(选择)->确定
- 在Ubuntu下安装ovs-dpdk
在Ubuntu下安装ovs-dpdk 参考资料:https://software.intel.com/zh-cn/articles/using-open-vswitch-with-dpdk-on-ub ...
- 【腾讯Bugly干货分享】微信终端跨平台组件 mars 系列(二) - 信令传输超时设计
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/9DJxipJaaBC8yC-buHgnTQ 作者简介: ...
- Nodejs之MEAN栈开发(六)---- 用Angular创建单页应用(上)
在上一节中我们学会了如何在页面中添加一个组件以及一些基本的Angular知识,而这一节将用Angular来创建一个单页应用(SPA).这意味着,取代我们之前用Express在服务端运行整个网站逻辑的方 ...