研究手写识别的时候看到了zinnia,就进行了测试,存在问题是zinnia书写依赖笔画顺序,而且没有找到更多的可以用于训练的数据。

zinnia介绍

zinnia是一个基于svm的开源的手写识别库。zinnia简单地接收用户笔划作为一系列坐标数据,并输出按SVM置信度排序的n个最佳字符。为了保持可移植性,Zinnia没有任何渲染功能。此外,Zinnia还提供训练模块,使我们能够以低成本创建任何手写识别系统。

特点

  • 支持向量机的实用精度

  • 便携紧凑的设计 - POSIX / Windows(取决于C ++ / STL)

  • 线程安全的C / C ++ / Perl / Ruby / Python库

  • 实用识别速度(50-100字符 /秒)

  • 快速训练

参考 zinnia的介绍:http://taku910.github.io/zinnia/

zinnia属于联机文字识别,包含预处理、特征提取和分类识别过程。

https://blog.csdn.net/stellar0/article/details/8741772

zinnia的使用

编译zinnia

从git上下载源码https://github.com/taku910/zinnia

打开VS2017命令行工具,进入zinnia源码文件目录

编译,使用指令”nmake -f Makefile.msvc”

生成 zinnia.lib,zinnia.dll文件。

使用zinnia:

1.创建zinnia::Recognizer,加载model文件

2.创建zinnia::Character,把书写的点坐标传进来

3.zinnia::Recognizer进行识别,得到一组包含识别的字和对应相似度的结果

注意点:

1.书写顺序会影响识别的结果,导致结果特别不准确

2.zinnia::Character需要设置字符的高宽,当只在一个小的区域书写,设置高宽很大时,相当于拿这个小的区域去和一个字的一部分去比较,取出最相近的。所以代码里面有根据点来确定一个区域,根据此区域设置zinnia::Character的高宽。

代码

.h文件:

#ifndef PAINTWIDGET_H
#define PAINTWIDGET_H#include <QWidget>
#include <QMap>class PaintWidget : public QWidget
{Q_OBJECT
public:explicit PaintWidget(QWidget *parent = nullptr);void clear();void init();void recignize();protected:void paintEvent(QPaintEvent *event);void mousePressEvent(QMouseEvent *event);void mouseMoveEvent(QMouseEvent * e);void mouseReleaseEvent(QMouseEvent * e);bool event(QEvent *event);private:void resizeRect(QPoint p);void adjustPoints();signals:void sigResult(QMap<QString, float> result);public slots:private:QImage *m_pCanvas = nullptr;QPainter *m_pPainter = nullptr;//临时画布的painterQPoint m_posLast;QMap<QString, float> m_result;QRect m_rect;std::vector<QPoint> m_vecPoints; //一个笔画所含的点,目前是把std::vector<std::vector<QPoint>> m_vecPointsList; // 里面的vector为一个笔画,外面一层为所有笔画集合
};#endif // PAINTWIDGET_H

.cpp文件:

#include "paintwidget.h"
#include <QPainter>
#include <QDebug>
#include <QImage>
#include <QMouseEvent>
#include <QApplication>
#include "zinnia/zinnia.h"
PaintWidget::PaintWidget(QWidget *parent) : QWidget(parent)
{}void PaintWidget::init()
{m_pCanvas = new QImage(this->size(),QImage::Format_ARGB32_Premultiplied);m_pCanvas->fill(Qt::transparent);qInfo()<<this->size();m_pPainter = new QPainter(m_pCanvas);
//    m_pPainter->setPen(Qt::black);m_pPainter->setRenderHint(QPainter::Antialiasing, true);m_pPainter->setCompositionMode(QPainter::CompositionMode_Source);m_pPainter->setPen(QPen(Qt::red,3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
}void PaintWidget::clear()
{m_vecPointsList.clear();m_pCanvas->fill(Qt::transparent);update();
}void PaintWidget::recignize()
{// 汉字识别zinnia::Recognizer *recognizer = zinnia::Recognizer::create();QString strPath = QApplication::applicationDirPath()+"/handwriting-zh_CN.model";qInfo()<<__FUNCTION__<<strPath;/*初始化汉字库*/if (!recognizer->open( strPath.toStdString().data() )){qInfo()<<__FUNCTION__<<"open model fail";return;}zinnia::Character *character = zinnia::Character::create();if(m_vecPointsList.size()<=0){qInfo()<<__FUNCTION__<<"no points";return;}character->clear();
//    character->set_width(this->width());
//    character->set_height(this->height());qInfo()<<m_rect;character->set_width(m_rect.width());character->set_height(m_rect.height());adjustPoints();for ( unsigned int i = 0 ; i < m_vecPointsList.size() ; i++ ){std::vector<QPoint> vecTmp = m_vecPointsList[i];for ( unsigned int j = 0 ; j < vecTmp.size() ; j++ ){character->add( i , vecTmp[j].x() , vecTmp[j].y() );}}zinnia::Result *result = recognizer->classify( *character , m_vecPointsList.size()/*m_vecPoints.size() / 2 +1*/ );if ( !result ) return;m_result.clear();for ( size_t i = 0 ; i < result->size() ; ++i ){std::string str1 = result->value(i);float score = result->score(i);QString qs = str1.c_str();qInfo()<<qs<<score;m_result.insert(qs, score);}emit sigResult(m_result);delete result;delete character;delete recognizer;m_vecPoints.clear();m_vecPointsList.clear();
}void PaintWidget::paintEvent(QPaintEvent *event)
{QPainter painter(this);painter.drawImage(0,0,*m_pCanvas);}void PaintWidget::mousePressEvent(QMouseEvent *event)
{QPoint pos = event->pos();qInfo()<<"mouse press"<<pos;m_posLast = pos;m_pPainter->drawPoint(pos);resizeRect(pos);m_vecPoints.push_back(pos);}void PaintWidget::mouseMoveEvent(QMouseEvent *event)
{QPoint pos = event->pos();m_pPainter->drawLine(m_posLast, pos);m_vecPoints.push_back(pos);m_posLast = pos;resizeRect(pos);update();
}void PaintWidget::mouseReleaseEvent(QMouseEvent *event)
{qInfo()<<__FUNCTION__<<event->pos();m_vecPointsList.push_back( m_vecPoints );m_vecPoints.clear();
}bool PaintWidget::event(QEvent *event)
{switch(event->type()){case QEvent::TouchBegin:mousePressEvent(static_cast<QMouseEvent*>(event));break;case QEvent::TouchUpdate:mouseMoveEvent(static_cast<QMouseEvent*>(event));break;case QEvent::TouchEnd:mouseReleaseEvent(static_cast<QMouseEvent*>(event));break;}return QWidget::event(event);
}void PaintWidget::resizeRect(QPoint p)
{if(m_vecPointsList.size() == 0 && m_vecPoints.size()==0){m_rect.setTopLeft(p);m_rect.setBottomRight(p);qInfo()<<__FUNCTION__<<"first point";}else{int x = p.x();int y = p.y();if(x<m_rect.left()){m_rect.setLeft(x);}else if(x>m_rect.right()){m_rect.setRight(x);}if(y<m_rect.top()){m_rect.setTop(y);}else if(y>m_rect.bottom()){m_rect.setBottom(y);}}
}void PaintWidget::adjustPoints()
{int x = m_rect.left();int y = m_rect.top();for (unsigned int i = 0 ; i < m_vecPointsList.size() ; i++){std::vector<QPoint> vecTmp = m_vecPointsList[i];for (unsigned int j = 0 ; j < vecTmp.size() ; j++){QPoint p = m_vecPointsList[i][j];m_vecPointsList[i][j] = QPoint(p.x()-x, p.y()-y);}}
}

使用zinnia库进行中文手写识别相关推荐

  1. 中文手写识别--wacom

    Wacom公司成立于1983年,以"通过自然直观的用户界面技术拉近人与技术的距离"为愿景.这一愿景已促使Wacom成为世界领先的数位板系 统.笔感应式数位屏系统和数字界面解决方案的 ...

  2. tensorflow+python flask进行手写识别_python+flask搭建CNN在线识别手写中文网站!简直太屌了!...

    原标题:python+flask搭建CNN在线识别手写中文网站!简直太屌了! 使用python+flask搭建的一个网站,然后从网页的写字板上获取鼠标手写的汉字经过转码后传回后台,并经过图片裁剪处理之 ...

  3. (手写识别) Zinnia库及其实现方法研究

    Zinnia库及其实现方法研究 (转) zinnia是一个开源的手写识别库.采用C++实现.具有手写识别,学习以及文字模型数据制作转换等功能. 项目地址 [http://zinnia.sourcefo ...

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

    若该文为原创文章,未经允许不得转载 原博主博客地址:https://blog.csdn.net/qq21497936 原博主博客导航:https://blog.csdn.net/qq21497936/ ...

  5. densenet tensorflow 中文汉字手写识别

    densenet 中文汉字手写识别,代码如下: import tensorflow as tf import os import random import math import tensorflo ...

  6. 【转载】Windows下Tesseract4.0识别与中文手写字体训练

    一 . tesseract 4.0 安装及使用 1. tesseract 4.0 安装 安装包下载地址: http://digi.bib.uni-mannheim.de/tesseract/tesse ...

  7. Windows下Tesseract4.0识别与中文手写字体训练

    一 . tesseract 4.0 安装及使用 1. tesseract 4.0 安装 安装包下载地址: http://digi.bib.uni-mannheim.de/tesseract/tesse ...

  8. 中文手写数据生成基于paddleocr和textrenderer-大幅提高中文识别准确率

    文章目录 参考 一.textrenderer更多参数解释 二.准备手写字体文件 效果展示 参考 主要是参考了这位大佬的工作 ,大佬说生成都是灰度图,因为考虑样本多样性,主要介绍如何生成彩色图片,字典文 ...

  9. Tensorflow之基于MNIST手写识别的入门介绍

    Tensorflow是当下AI热潮下,最为受欢迎的开源框架.无论是从Github上的fork数量还是star数量,还是从支持的语音,开发资料,社区活跃度等多方面,他当之为superstar. 在前面介 ...

最新文章

  1. Spring Boot 3.0 M1 发布,正式弃用 Java 8,最低要求 Java 17。。。
  2. 车道检测源码分析系列
  3. 手机浏览器不支持jquery_简洁清新实用适合做浏览器主页 支持手机浏览器
  4. 谈Elasticsearch下分布式存储的数据分布
  5. 【C++ grammar】对象指针、对象数组、函数参数
  6. 产品运营 跨境支付_餐饮网店的运营 跨境支付哪个平台最好
  7. java的课后作业咋写_写的简单的java第三季的课后作业
  8. Security Tutorials系列文章第七章:User-Based Authorization(下)
  9. python + opencv: 解决不能读取视频的问题
  10. Go Elasticsearch 查询快速入门
  11. python怎么使用base64_python常用库之base64
  12. spring boot+Quartz+数据库存储
  13. 安川机器人原点丢失_安川机器人原点及校准浅析
  14. hutool实战(带你掌握里面的各种工具)目录
  15. 3.取色精灵V2.0-非模态对话框自建消息队列、VS2008风格对话框、使用Common Controls、悬浮透明窗口、使用SLIDER控件
  16. IEEE邮件曝光,禁止华为员工审稿!
  17. 群晖DOCKER搭建自动签到 PT网站再也不怕忘记登录了
  18. 华为+android+root权限获取root,华为手机root权限获取方法
  19. eventscheduler mysql_Mysql 中的事件 事件调度器(Event Scheduler)
  20. 身份证ocr识别开源方案_多因素身份验证的开源替代方案:privacyIDEA

热门文章

  1. 同调代数基础(全书)
  2. 2022-06-信息论-吴军
  3. 用STM32单片机ADC+NTC热敏电阻采集温度的设计思路 | 附参考电路
  4. 三分钟编程系列,教你用C++制作3D台球游戏,有源代码!
  5. JavaScript 随机数
  6. MIT 18.06 线性代数公开课笔记 Lecture07Ax=0: 主变量, 特解
  7. 车载串行器MAX96717F的使用
  8. 读论文:Segment Anything
  9. Python数据存储与压缩
  10. 21考研961常见问题