最近在做一个项目需要给外接触摸屏加手写输入法,不要求精确识别。于是乎在网上搜索了一下发现有很多人上手过Zinnia。就研究了一下发现基本能满足我的需要,记录一些事情,给后面踩坑的人一点帮助吧。
1.SDK下载
Linux推荐GitHub:https://github.com/taku910/zinnia
Windows推荐sourceforge.:https://master.dl.sourceforge.net/project/zinnia/OldFiles/zinnia-0.01.zip
这里主要是Windows的
2.model下载(注:这个主要是下载txt文件,然后训练成模型)
注意这个文件用7解压两次才能完全打开
3.训练模型
把zinnia-tomoe-0.6.0-20080911文件夹里的handwriting-zh_CN.model.txt复制到zinnia-0.01里面,然后打开cmd,进入zinnia-0.01里面,输入下面代码,等待model文件生成完毕。
zinnia_convert.exe handwriting-zh_CN.model.txt zinnia.model
4.建立VS工程,这步就略过了哈,win32 X86的就行
5.配置环境
将下面三个复制进工程里,添加头文件和lib文件路径,怕麻烦的直接和其他代码文件放一起,还有model文件也拷贝过来
6.写代码,不知道为啥例子的C++代码好像不能用 ,我用的是C的,直接上代码不解释
// ZinniaDemo.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include "zinnia.h"
std::string UTF8ToGB(const char* str)
{
std::string result;
WCHAR *strSrc;
LPSTR szRes;
//获得临时变量的大小
int i = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
strSrc = new WCHAR[i + 1];
MultiByteToWideChar(CP_UTF8, 0, str, -1, strSrc, i);
//获得临时变量的大小
i = WideCharToMultiByte(CP_ACP, 0, strSrc, -1, NULL, 0, NULL, NULL);
szRes = new CHAR[i + 1];
WideCharToMultiByte(CP_ACP, 0, strSrc, -1, szRes, i, NULL, NULL);
result = szRes;
delete[]strSrc;
delete[]szRes;
return result;
}
int main()
{
zinnia_recognizer_t *recognizer = zinnia_recognizer_new();
zinnia_character_t *character = zinnia_character_new();
if (!zinnia_recognizer_open(recognizer, "zinnia.model"))
{
fprintf(stderr, "ERROR1: %s\n", zinnia_recognizer_strerror(recognizer));
system("pause");
return -1;
}
//设置纸张的大小
zinnia_character_set_width(character,100);
zinnia_character_set_height(character,100);
//注意这里,一笔一划的开始和结束的点,0对应两个点;1也对应两个点;然后0和1是笔画的先后顺序,以此类推
zinnia_character_add(character, 0, 40, 50);
zinnia_character_add(character, 0, 100, 52);
zinnia_character_add(character, 1, 10, 81);
zinnia_character_add(character, 1, 120, 84);
//zinnia_character_add(character, 2, 20, 20);
//zinnia_character_add(character, 2, 30, 20);
//zinnia_character_add(character, 3, 30, 17);
//zinnia_character_add(character, 3, 40, 20);
//zinnia_character_add(character, 4, 40, 20);
//zinnia_character_add(character, 4, 50, 20);
//zinnia_character_add(character, 5, 50, 20);
//zinnia_character_add(character, 5, 60, 20);
//zinnia_character_add(character, 6, 60, 20);
//zinnia_character_add(character, 6, 60, 20);
//zinnia_character_add(character, 6, 70, 20);
//zinnia_character_add(character, 7, 70, 20);
//zinnia_character_add(character, 7, 80, 20);
char InPutStr[1024];
zinnia_character_to_string(character, InPutStr, 1024);
{
zinnia_result_t *newResult = zinnia_recognizer_classify(recognizer, character, 5);
size_t i;
if (!newResult)
{
fprintf(stderr, "ERROR: %s \n", zinnia_recognizer_strerror(recognizer));
system("pause");
return -1;
}
for (i = 0; i < zinnia_result_size(newResult); i++)
{
std::string Re=UTF8ToGB(zinnia_result_value(newResult, i));
fprintf(stdout, "%s\t%f\n", Re.c_str(),zinnia_result_score(newResult, i));
}
zinnia_result_destroy(newResult);
}
zinnia_character_destroy(character);
zinnia_recognizer_destroy(recognizer);
system("pause");
return 0;
}
7.结果(上面代码是汉字“二”)
8.再加一个MFC版本的效果图