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

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

若该文为原创文章,未经允许不得转载

原博主博客地址:https://blog.csdn.net/qq21497936

原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062

本文章博客地址:https://blog.csdn.net/qq21497936/article/details/86612009

各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究

 

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

 

前话

       项目中有手写输入识别需求,转而研究手写输入算法。

 

Zinnia介绍

      zinnia是一个开源的手写识别库,采用C++实现,具有手写识别,学习以及文字模型数据制作转换等功能,且该库拥有较好的可移植性。

      zinnia手写输入为用户笔画坐标作为一系列坐标数据,并输出按SVM置信度排序的n个最佳字符。

      zinnia库具备以下特点:

  • 支持向量机的实用精度
  • 便携紧凑的设计 - POSIX / Windows(取决于C ++ / STL)
  • 线程安全的C / C ++ / Perl / Ruby / Python
  • 实用识别速度(50-100 /秒)
  • 快速培训

Zinnia库下载

      下载地址:https://github.com/taku910/zinnia

      (zinnia主页所指下载地址已经404…)

       

      提供csdn下载地址:https://download.csdn.net/download/qq21497936/10934234

 

使用VS2017编译Zinnia库

步骤一:打开VS2017命令行工具,切换到源码目录

         

         

步骤二:编译,使用指令”nmake -f Makefile.msvc”

       

       就这么轻松愉快的编译完了,如下图:

     

       

       将其模块化,参照jpeglib的模块化方法:https://blog.csdn.net/qq21497936/article/details/86155043

 

训练模型文件

       为了给zinnia提供识别的基础数据,需要制作训练数据,训练数据用S表达式编写。一般而言,更多数据会产生更好的质量。到目前为止,百日草只支持批量训练,涉及到3个应用,如下:

  • zinnia_learn.exe:用于对指定元数据进行学习;
  • zinnia_convert程序将文本模型转换为二进制模型,可以压缩;
  • zinnia.exe:我们用于测试模型识别文件;

 

模型文件格式

(character (value あ) (width 300) (height 300) (strokes ((54 58)(249 68)) ((147 10)(145 201)(182 252)) ((224 103)(149 230)(82 240)(53 204)(86 149)(182 139)(240 172)(248 224)(228 250))))
(character (value い) (width 300) (height 300) (strokes ((56 63)(43 213)(67 259)(94 243)) ((213 66)(231 171)(208 217))))
(character (value う) (width 300) (height 300) (strokes ((102 35)(187 45)) ((73 121)(167 105)(206 139)(198 211)(135 275))))
(character (value え) (width 300) (height 300) (strokes ((140 19)(162 38)) ((62 105)(208 100)(51 263)(128 205)(188 268)(260 252))))
(character (value お) (width 300) (height 300) (strokes ((64 94)(240 98)) ((148 35)(159 129)(140 199)(105 247)(64 228)(101 161)(192 161)(222 223)(189 257)) ((223 49)(253 89))))

       

训练模型(可进行压缩)

       

       得到模型文件data.mode(二进制),至于多生成得data.mode.txt(文本文件)是一种独立于体系结构得格式,zinnia只能添加二进制文件,但是截图对比预留出来,以后也许用得到呢?

 

输入文件格式

       实际与模型文件格式类似,只是少了“(value う)”这一段,如下:

(character (width 300) (height 300) (strokes ((54 58)(249 68)) ((147 10)(145 201)(182 252)) ((224 103)(149 230)(82 240)(53 204)(86 149)(182 139)(240 172)(248 224)(228 250))))
(character (width 300) (height 300) (strokes ((56 63)(43 213)(67 259)(94 243)) ((213 66)(231 171)(208 217))))
(character (width 300) (height 300) (strokes ((102 35)(187 45)) ((73 121)(167 105)(206 139)(198 211)(135 275))))
(character (width 300) (height 300) (strokes ((140 19)(162 38)) ((62 105)(208 100)(51 263)(128 205)(188 268)(260 252))))
(character (width 300) (height 300) (strokes ((64 94)(240 98)) ((148 35)(159 129)(140 199)(105 247)(64 228)(101 161)(192 161)(222 223)(189 257)) ((223 49)(253 89))))

 

测试识别(直接使用模型文件)

zinnia.exe -m data.model test.txt

       使用模型”data.model”(二进制,非文本的),输入的文件为”test.txt”

   

       由此,我们可以看出zinnia库识别的特点,应该是相似度,相似度越高越在前面,越低在越后面,那么风马牛不相及也有个相似度(负数),应该都能输出,我们取前面一部分(约5-10个)就好了,其实也可以取相似度,我们仔细查看识别出的数据特点,分析如下图:

       

       所以根据数据特点,果断给这个下定义,认为就是相似度(阅读代码实际也是,相似得分)。

 

使用VS2017建立C++程序测试Demo

步骤一:建立VC++空工程

       参照jpeglib测试demo:https://blog.csdn.net/qq21497936/article/details/86155043

步骤二:加入头文件路径,库路径,库命,在代码中添加引入库

       参照jpeglib测试demo:https://blog.csdn.net/qq21497936/article/details/86155043

步骤三:拷贝代码 (注意运行代码,需要拷贝之前建立的模型data.model)

#include <iostream>
#include "zinnia.h"
static const char *input =
"(character (width 1000)(height 1000)"
"(strokes ((243 273)(393 450))((700 253)(343 486)(280 716)(393 866)(710 880))))";
#pragma comment(lib, "libzinnia.lib")
int main(int argc, char **argv) {
  zinnia::Recognizer *recognizer = zinnia::Recognizer::create();
  if (!recognizer->open("D:\\compile\\zinnia\\Demo\\Debug\\data.model")) 
  {
    std::cerr << recognizer->what() << std::endl;
    return -1;
  }
  // 第一次识别(输入文件)
  zinnia::Character *character = zinnia::Character::create();
  if (!character->parse(input)) {
    std::cerr << character->what() << std::endl;
    return -1;
  }
  {
    zinnia::Result *result = recognizer->classify(*character, 1);
    if (!result) 
    {
      std::cerr << recognizer->what() << std::endl;
      return -1;
    }
    for (size_t i = 0; i < result->size(); ++i) 
    {
      std::cout << "parse input i = " << i 
                << " result = " << result->value(i)    
                << "\t score = " << result->score(i) << std::endl;
    }
    delete result;
  }
  // 第二次识别(函数输入特征点)
  character->clear();
  character->set_width(300);
  character->set_height(300);
  character->add(0, 51, 29);
  character->add(0, 117, 41);
  character->add(1, 99, 65);
  character->add(1, 219, 77);
  character->add(2, 27, 131);
  character->add(2, 261, 131);
  character->add(3, 129, 17);
  character->add(3, 57, 203);
  character->add(4, 111, 71);
  character->add(4, 219, 173);
  character->add(5, 81, 161);
  character->add(5, 93, 281);
  character->add(6, 99, 167);
  character->add(6, 207, 167);
  character->add(6, 189, 245);
  character->add(7, 99, 227);
  character->add(7, 189, 227);
  character->add(8, 111, 257);
  character->add(8, 189, 245);
  {
    zinnia::Result *result = recognizer->classify(*character, 1);
    if (!result) 
    {
      std::cerr << recognizer->what() << std::endl;
      return -1;
    }
    for (size_t i = 0; i < result->size(); ++i) 
    {
      std::cout << "parase input i = " << i 
                << " result = " << result->value(i) 
                << "\t score = " << result->score(i) << std::endl;
    }
    delete result;
  }
  delete character;
  delete recognizer;
  getchar();
  return 0;
}

Demo效果

       如下图,模型只有5个,所以不准,框架搭好,下一步节主要研究数据模型:

       

 

Demo下载地址

       https://download.csdn.net/download/qq21497936/10934243

 

拓展1:文本模型可转换为c/c++源文件

      (略)

 

拓展2:模型可进一步压缩(损失识别精度)

       

 

 

原博主博客地址:https://blog.csdn.net/qq21497936

原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062

本文章博客地址:https://blog.csdn.net/qq21497936/article/details/86612009


相关文章
|
2月前
|
C++
VS2019编译VTK-9.1.0+Qt5.15.2
本文介绍了在VS2019和Qt 5.15.2环境下编译VTK 9.1.0的过程,包括成功编译无警告和错误的截图、修改的pro文件内容,以及在QML中加入VTK的失败尝试和参考链接。
|
2月前
|
C语言 Android开发 C++
基于MTuner软件进行qt的mingw编译程序的内存泄漏检测
本文介绍了使用MTuner软件进行Qt MinGW编译程序的内存泄漏检测的方法,提供了MTuner的下载链接和测试代码示例,并通过将Debug程序拖入MTuner来定位内存泄漏问题。
基于MTuner软件进行qt的mingw编译程序的内存泄漏检测
|
2月前
|
C++
vtkdicom0.8_vtk9.2_dcmtk3.6.7_qt6.2编译OK
本文介绍了如何编译整合VTK 9.2、DICOM 0.8、DCMTK 3.6.7和Qt 6.2的步骤,包括安装Qt、CMake配置以及确认相关路径和版本设置。
vtkdicom0.8_vtk9.2_dcmtk3.6.7_qt6.2编译OK
|
2月前
|
Unix 网络虚拟化 C++
VS2022+Qt5.14.2成功编译MITK2022.10
使用VS2022和Qt5.14.2成功编译MITK2022.10的过程,包括编译结果的截图、遇到的编译问题的解决方法、两个重要的注意事项(patch文件格式的修改和ITK-gitclone-lastrun文件的存在),以及参考链接。文中详细描述了如何解决编译过程中遇到的错误C2220和警告C4819,以及如何修改文件编码和尾行格式。
130 1
VS2022+Qt5.14.2成功编译MITK2022.10
|
2月前
编译QCefView+VS2019+QT5.15.2
本文介绍了如何编译QCefView项目,并在VS2019和Qt 5.15.2环境下集成,包括编译结果、要点、cmake部署Qt的方法和相关参考链接。
122 1
编译QCefView+VS2019+QT5.15.2
|
2月前
|
人工智能
三战VS2019编译VTK7.1+Qt5.15.2
本文记录了作者在VS2019环境下编译VTK 7.1与Qt 5.15.2的历程,包括正确配置方法、遇到的编译错误以及解决过程。
|
2月前
|
人工智能 C++
初步编译QT5.15.2+VS2019+VTK8.2.0
本文介绍了在VS2019中编译QT 5.15.2和VTK 8.2.0的过程,包括编译结果、cmake库编译配置和cmake应用配置脚本,以及推荐的参考链接。
124 4
|
2月前
|
计算机视觉
vs2019_qt6.2.4_dcmtk3.6.7_vtk9.2.2_itk5.3_opencv4.6.0编译记录
这篇文章记录了使用VS2019编译Qt6.2.4、DCMTK3.6.7、VTK9.2.2、ITK5.3和OpenCV4.6.0的过程,包括下载和编译步骤,并提供了遇到编译错误时的解决方案和参考链接。
vs2019_qt6.2.4_dcmtk3.6.7_vtk9.2.2_itk5.3_opencv4.6.0编译记录
|
2月前
|
C语言 C++ Windows
QT多插件通信框架CTK编译记录
本文记录了编译QT多插件通信框架CTK的过程,包括编译结果截图、部署配置、Log4Qt编译配置、参考链接和拓展资料。文中提供了详细的编译步骤和配置文件示例,以及相关的资源链接。
QT多插件通信框架CTK编译记录
|
2月前
|
机器学习/深度学习 Java 计算机视觉
opencv4.5.5+qt5.15.2+vtk9.1+mingw81_64编译记录
本文记录了使用mingw81_64编译OpenCV 4.5.5、Qt 5.15.2、VTK 9.1的详细过程,包括编译结果截图、编译步骤、遇到的问题及其解决方案,以及相关参考链接。文中还提到了如何编译boost源码为静态库,并提供了测试代码示例。
opencv4.5.5+qt5.15.2+vtk9.1+mingw81_64编译记录