前面我们使用Azure Face实现了人脸识别、使用Azure表格识别器提取了表格里的数据。这次我们试试使用Azure墨迹识别API来对笔迹进行识别。

墨迹识别

墨迹识别器认知服务提供基于云的 REST API 用于分析和识别数字墨迹内容。与使用光学字符识别 (OCR) 的服务不同,该 API 需要使用数字墨迹笔划数据作为输入。数字墨迹笔划是 2D 点(X,Y 坐标,表示数字手写笔或手指的动作)的时序集。然后,墨迹识别器会识别输入中的形状和手写内容,并返回包含所有已识别实体的 JSON 响应。

引用自微软文档

它不是ocr对图像进行识别,而是对墨迹数据进行识别。墨迹数据的原理主要是一些手写输入设备,比如平板,手写板等。

创建墨迹识别资源

跟前面的内容一样,在portal控制台找到墨迹识别,点击创建,取一个实例名。墨迹识别也是一个免费服务,定价选F0方案,额度为5次/分,20000事务/月。

获取秘钥和终结点

我们调用墨迹识别API需要秘钥跟终结点信息。点击菜单“密钥和终结点”查看信息。

新建一个WPF项目

我们这次同样实现一个WPF小程序。界面上放置一个InkCanvas用来手写,一个文本框用来显示识别的文本,一个按钮用来触发识别。

MainWindow.xaml

修改MainWindow.xaml为如下代码:

<Window x:Class="InkRec2.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"mc:Ignorable="d"xmlns:local="clr-namespace:NoteTaker"xmlns:controls="clr-namespace:Microsoft.Toolkit.Wpf.UI.Controls;assembly=Microsoft.Toolkit.Wpf.UI.Controls"Title="MainWindow"><Grid ><Grid.RowDefinitions><RowDefinition Height="4*" /><RowDefinition Height="1*" /><RowDefinition Height="50" /></Grid.RowDefinitions><Border Grid.Row ="0" BorderBrush="Black" BorderThickness="1"><controls:InkCanvas x:Name="inkCanvas" Loaded="inkCanvas_Loaded"/></Border><Border Grid.Row ="1" BorderBrush="Black" BorderThickness="1"><ScrollViewer><TextBox x:Name="output" FontSize="18" TextWrapping="Wrap"/></ScrollViewer></Border><StackPanel Grid.Row="2" Orientation="Horizontal"><Button Click="Button_InkRec">开始识别</Button></StackPanel></Grid>
</Window>

注意:InkCanvas控件需要使用的是Microsoft.Toolkit.Wpf.UI.Controls包下的,如果本地没有使用nuget进行安装

采集墨迹

inkCanvas load事件里设置输入设备的类型:

   private void inkCanvas_Loaded(object sender, RoutedEventArgs e){inkCanvas.InkPresenter.InputDeviceTypes = CoreInputDeviceTypes.Mouse | CoreInputDeviceTypes.Pen | CoreInputDeviceTypes.Touch;}

先定义几个模型用来存储墨迹数据:

    public class InkStroke{public int id { get; set; }public string points { get; set; }}public class InkData{public string language { get; set; }public List<InkStroke> strokes { get; set; }}

从InkCanvas获取墨迹数据组装成InkData:

        private InkData GetInkData(){var data = new InkData();data.language = "zh-CN";data.strokes = new List<InkStroke>();int id = 0;foreach (var stroke in this.inkCanvas.InkPresenter.StrokeContainer.GetStrokes()){var points = stroke.GetInkPoints();var convertPoints = ConvertPixelsToMillimeters(points);var inkStorke = new InkStroke();inkStorke.id = id++;var sb = new StringBuilder();foreach (var point in convertPoints){sb.Append(point.X);sb.Append(",");sb.Append(point.Y);sb.Append(",");}inkStorke.points = sb.ToString().TrimEnd(',');data.strokes.Add(inkStorke);}return data;}private List<System.Windows.Point> ConvertPixelsToMillimeters(IReadOnlyList<InkPoint> pointsInPixels){float dpiX = 96.0f;float dpiY = 96.0f;var transformedInkPoints = new List<System.Windows.Point>();const float inchToMillimeterFactor = 25.4f;foreach (var point in pointsInPixels){var transformedX = (point.Position.X / dpiX) * inchToMillimeterFactor;var transformedY = (point.Position.Y / dpiY) * inchToMillimeterFactor;transformedInkPoints.Add(new System.Windows.Point(transformedX, transformedY));}return transformedInkPoints;}

调用墨迹API

这里需要前面复制好的密钥跟终结点地址。识别其实很简单,就是把墨迹数据转换成json后给服务器发生一个put请求,识别成功后就会返回一个json字符串的结果。

        private async Task<string> InkRec(InkData data){string inkRecognitionUrl = "/inkrecognizer/v1.0-preview/recognize";string endPoint = "x";string subscriptionKey = "x";using (HttpClient client = new HttpClient { BaseAddress = new Uri(endPoint) }){System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey);var jsonData = JsonConvert.SerializeObject(data);var content = new StringContent(jsonData, Encoding.UTF8, "application/json");var res = await client.PutAsync(inkRecognitionUrl, content);if (res.IsSuccessStatusCode){var result = await res.Content.ReadAsStringAsync();return result;}else{var err = $"ErrorCode: {res.StatusCode}";return err;}}}

解析识别结果

识别成功后,结果会以json字符串的形式进行返回。结果是一个数组,里面存放了每一个笔迹的识别结果,以及最终的识别结果。
结果示例:

{"recognitionUnits":[{"alternates":[{"category":"inkWord","recognizedString":"乖"},{"category":"inkWord","recognizedString":"黍"},{"category":"inkWord","recognizedString":"秉"},{"category":"inkWord","recognizedString":"乗"},{"category":"inkWord","recognizedString":"埀"}],"boundingRectangle":{"height":48.159999847412109,"topX":7.190000057220459,"topY":22.010000228881836,"width":35.639999389648438},"category":"inkWord","class":"leaf","id":4,"parentId":3,"recognizedText":"乘","rotatedBoundingRectangle":[{"x":41.490001678466797,"y":21.25},{"x":43.209999084472656,"y":69.239997863769531},{"x":7.8299999237060547,"y":70.5},{"x":6.1100001335144043,"y":22.520000457763672}],"strokeIds":[0,1,2,3,4,5,6,7,8,9]},{"alternates":[{"category":"inkWord","recognizedString":"風"},{"category":"inkWord","recognizedString":"夙"},{"category":"inkWord","recognizedString":"凤"},{"category":"inkWord","recognizedString":"凡"},{"category":"inkWord","recognizedString":"㶡"}],"boundingRectangle":
...
...

有了结果那么我们只要对其进行反序列化取出想要的识别结果就行了。

    public class InkRecResponse{public List<InkRecResponseUnit> recognitionUnits { get; set; }}public class InkRecResponseUnit{public string category { get; set; }public string recognizedText { get; set; }}private async void Button_InkRec(object sender, RoutedEventArgs e){var inkData = GetInkData();var response = await InkRec(inkData);var jsonObj = JsonConvert.DeserializeObject<InkRecResponse>(response);var recognizedText = jsonObj.recognitionUnits.First(o => o.category == "line").recognizedText;this.output.Text = recognizedText;}

运行一下

我们的程序写好了,运行一下。在canvas上随便写上几个汉字点击识别按钮。字虽然丑了点,但是结果还是完美的。

总结

使用Azure墨迹识别可以轻松的识别手写输入设备的笔迹。墨迹识别功能并不是见到的orc识别,它可以对每一个笔画进行识别,提供候选结果。以上代码虽然多,其实主要是获取墨迹数据比较麻烦,其实真正识别墨迹只是一个http put请求而已,这是非常简单的。有了这个API我们可以实现很多创意,比如稍微改进下上面的代码就可以实现手写文字的连续识别功能,一边写一边不断的识别,封装进平板就是一款可以实时识别手写板啦。

关注我的公众号一起玩转技术

Azure认知服务之使用墨迹识别功能识别手写汉字相关推荐

  1. Azure认知服务之表单识别器

    认知服务 Azure 认知服务的目标是帮助开发人员创建可以看.听.说.理解甚至开始推理的应用程序.Azure 认知服务中的服务目录可分为五大主要支柱类别:视觉.语音.语言.Web 搜索和决策.开发人员 ...

  2. 【微软 Azure 认知服务】零基础搭建微软 Azure AI 认知服务实验分享

    Azure人工智能认知服务实验 Azure认知服务(语音合成产品系列)是微软云服务里面的明星产品,基于行业领先的Hifi-net语音模型打造,可以提供高质量神经网络版声音,发音更准确.韵律更自然.高保 ...

  3. 用Azure认知服务开发一个语音翻译机,学英文很爽快

    最近CSDN开展了<0元试用微软 Azure人工智能认知服务,精美礼品大放送>,当前目前活动还在继续,热心的我已经第一时间报名参与,只不过今天才有时间实际的试用. 目前活动要求博文形式分享 ...

  4. 使用Azure认知服务快速搭建一个目标检测平台

    文章目录 前言 1. 认知服务 2. 环境配置 2.1 创建资源 2.2 创建python环境 3. 代码实现 3.1 图片检测 3.2 视频检测 4. 检测效果 结束语 前言   博主参与了由CSD ...

  5. azure云服务使用方法_使用Azure认知服务自动执行表单处理

    azure云服务使用方法 由机器学习提供支持的 Microsoft认知服务是一种向您的应用程序添加人工智能的简便方法,使您可以按需付费,访问各种有用的算法 . 与许多其他Web服务不同,它们正在不断发 ...

  6. Azure媒体服务的Apple FairPlay流功能正式上线

    在此我们高兴地宣布,Azure FairPlay Streaming服务已正式商用. FairPlay允许用户轻松构建解决方案,并可扩展到最新版本的Apple TV.Azure媒体服务可以结合现有的P ...

  7. 【0元试用微软 Azure人工智能认知服务】这个人脸识别功能太强大啦

    导读:这个由美丽的客服小姐姐提前申请好了企业试用的账号,个人的话还得需要visa卡. 官网地址:azure.cn 登录地址:portal.azure.cn 目录 1.简介 2.Azure 认知服务是什 ...

  8. 微软 Azure人工智能认知服务打造语音提醒喝水助手(带源码和演示地址)

    目录 一.写在前面 二.创建认知服务资源 1. 创建语音服务 2. 创建文本服务 三.语音提醒助手 1. 文本转语音,提醒我喝水 2. 语音转文本,我也能做回应 3. 文本分析,得出喝水频率 4. 实 ...

  9. 【0元试用微软 Azure人工智能认知服务】我做了个群聊天机器人

    前言 我这边参加了CSDN与微软Azure举办的0元试用微软Azure人工智能认知服务活动.第一次使用微软Azure 认知服务,老实说,还是满心期待的. 文章目录 前言 正式开始试用 环境 SDK的位 ...

最新文章

  1. 研究能力培养的阶梯: 盐趣一对一科研项目
  2. python安装好后打不开_windows的cmd中输入python后打不开python?
  3. Android 自定义控件打造史上最简单的侧滑菜单
  4. 转:精通JS正则表达式
  5. 混合样本数据增强(Mixed Sample Data Augmentation,MSDA)
  6. hibernate组件映射
  7. java hashmap getitem_java中HashMap使用
  8. 做游戏,学编程(C语言) 21 台球
  9. Centos--swoole平滑重启服务
  10. 在线超级外链发布工具
  11. win10cmd重置系统_win10命令行恢复出厂设置
  12. ACwing 149. 荷马史诗
  13. nls_lang环境变量linux设置,设置NLS_LANG环境变量
  14. 计算机行业英语期中考试,《计算机专业英语》期末考试试卷
  15. K8S 常见面试题总结
  16. 斐波那契数列前20项_短线交易的秘诀——斐波那契数列,数学界的“完美”公式!...
  17. 自用版:客服话术大全
  18. Linux鸟哥的私房菜读后感(菜鸟的读后感)
  19. springboot集成security
  20. 土地公公分管的土地范围是多少

热门文章

  1. SpringMVC4零配置--web.xml
  2. BZOJ1179 Atm //缩点+spfa
  3. 设置tableView的分割线从最左端开始
  4. UNIX环境高级编程笔记
  5. C#正则表达式编程(四)转致周公
  6. 【2006-1】【字符统计】
  7. CiberCut_5.6 标牌制作
  8. Office SharePoint Server 2007
  9. VR 技术加上 8K 画质! 2016 年里约奥运会亮点十足
  10. 关于高级导数的一个不等式估计