zoukankan      html  css  js  c++  java
  • 【WPF】提高InkAnalyer手写汉字识别的准确率

    最近项目中需要用到一个手写键盘,我们使用了WPF的InkCanvas+InkAnalyer来开发。

    按照文档,一般的代码写法如下:

                var analyzer = new InkAnalyzer();
                analyzer.AddStrokes(strokes, Constants.ChsLanguageId);
                analyzer.SetStrokesType(strokes, StrokeType.Writing);
    
                var status = analyzer.Analyze();
                if (status.Successful)
                {
                    return analyzer.GetAlternates()
                        .OfType<AnalysisAlternate>()
                        .Select(x => x.RecognizedString)
                        .ToArray();
                }
    
                analyzer.Dispose();

    不过,在实际跑起来之后,却发现识别精确度很低,经常会把一个字识别成好几个字,如果写的稍微远一点,则错误更多。

                                  一个简单的人字会被识别成两个笔画

                                 一个稍微写的开点的游字识别成了三个字

    这让我们非常苦恼,在网上查阅资料也没有相关的方案。

    经过我们仔细尝试后发现,如果我们把一个字连起来写一气呵成,识别率倒是上去了不少:

    但是,我们不可能要求用户所有字都一气呵成吧?

    就在这时,我们想到,既然不能要求用户把字一气呵成的写完,能不能通过程序让用户写的笔画“一气呵成”呢?

    有了这个灵感,简单改动,将代码改成如下的写法:

            /// <summary>
            /// 识别
            /// </summary>
            /// <param name="strokes">笔迹集合</param>
            /// <returns>候选词数组</returns>
            public string[] Recognize(StrokeCollection strokes)
            {
                if (strokes == null || strokes.Count == 0)
                    return Constants.EmptyAlternates;
    
                var stroke = GetCombinedStore(strokes);
    
                var analyzer = new InkAnalyzer();
                analyzer.AddStroke(stroke, Constants.ChsLanguageId);
                analyzer.SetStrokeType(stroke, StrokeType.Writing);
    
                var status = analyzer.Analyze();
                if (status.Successful)
                {
                    return analyzer.GetAlternates()
                        .OfType<AnalysisAlternate>()
                        .Select(x => x.RecognizedString)
                        .ToArray();
                }
    
                analyzer.Dispose();
    
                return Constants.EmptyAlternates;
            }
    
            private static Stroke GetCombinedStore(StrokeCollection strokes)
            {
                var points = new StylusPointCollection();
                foreach (var stroke in strokes)
                {
                    points.Add(stroke.StylusPoints);
                }
                return new Stroke(points);
            }

    注意,在这种写法里面,我们并不直接使用InkCanvas给出的StrokeCollection,而是重新创建了一个Stroke,这个Stroke的StylusPoints是把所有Stroke的StylusPoints都添加进去了,多个Stroke变成了一个Stroke,这下我们再试试:

    终于达到我们的要求了,呵呵

    希望能给大家带来帮助

    【附】如何启用手写识别:

    1、在控制面板中选择 程序和功能->添加/删除Windows组件,选择TabletPC组件功能。

    2、引用IACore.dll,IALoader.dll,IAWinFX.dll,Microsoft.Ink.Analysis.dll

    3、App.config里面需要设置:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/>
      </startup>
    </configuration>

    代码下载:http://files.cnblogs.com/RMay/WpfRecognize.7z

  • 相关阅读:
    Python学习(二十四)—— 前端基础之Bookstrap
    Python学习(二十三)—— 前端基础之jQuery
    Python心得基础篇【4】文件操作
    Python心得基础篇【3】基本知识
    Python心得基础篇【2】函数
    WCF使用net.tcp绑定的配置实例
    WCF:如何将net.tcp协议寄宿到IIS
    WCF使用net.Tcp绑定时的注意事项
    解决WCF跨机器调用时发生“调用方未由服务进行身份验证”的错误
    在IIS中部署好WCF服务站点后,本机访问服务无问题,局域网中其他电脑访问不到
  • 原文地址:https://www.cnblogs.com/RMay/p/improve_inkanalyer_recognization.html
Copyright © 2011-2022 走看看