加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-15 08:15:21 所属栏目:安全 来源:网络整理
导读:前面我们使用Azure Face实现了人脸识别、使用Azure表格识别器提取了表格里的数据。这次我们试试使用Azure墨迹识别API来对笔迹进行识别。 墨迹识别 墨迹识别器认知服务提供基于云的 REST API 用于分析和识别数字墨迹内容。 与使用光学字符识别 (OCR) 的服务不

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

墨迹识别

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

引用自微软文档

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

创建墨迹识别资源

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

d8uQJI.png

获取秘钥和终结点

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

d8ulWt.png

新建一个WPF项目

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

d31qhj.png

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":"黍"},"recognizedString":"秉"},"recognizedString":"                        

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读