使用zinnia库进行中文手写识别
研究手写识别的时候看到了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库进行中文手写识别相关推荐
- 中文手写识别--wacom
Wacom公司成立于1983年,以"通过自然直观的用户界面技术拉近人与技术的距离"为愿景.这一愿景已促使Wacom成为世界领先的数位板系 统.笔感应式数位屏系统和数字界面解决方案的 ...
- tensorflow+python flask进行手写识别_python+flask搭建CNN在线识别手写中文网站!简直太屌了!...
原标题:python+flask搭建CNN在线识别手写中文网站!简直太屌了! 使用python+flask搭建的一个网站,然后从网页的写字板上获取鼠标手写的汉字经过转码后传回后台,并经过图片裁剪处理之 ...
- (手写识别) Zinnia库及其实现方法研究
Zinnia库及其实现方法研究 (转) zinnia是一个开源的手写识别库.采用C++实现.具有手写识别,学习以及文字模型数据制作转换等功能. 项目地址 [http://zinnia.sourcefo ...
- Qt之手写识别开发笔记:Zinnia介绍、编译、使用以及Demo
若该文为原创文章,未经允许不得转载 原博主博客地址:https://blog.csdn.net/qq21497936 原博主博客导航:https://blog.csdn.net/qq21497936/ ...
- densenet tensorflow 中文汉字手写识别
densenet 中文汉字手写识别,代码如下: import tensorflow as tf import os import random import math import tensorflo ...
- 【转载】Windows下Tesseract4.0识别与中文手写字体训练
一 . tesseract 4.0 安装及使用 1. tesseract 4.0 安装 安装包下载地址: http://digi.bib.uni-mannheim.de/tesseract/tesse ...
- Windows下Tesseract4.0识别与中文手写字体训练
一 . tesseract 4.0 安装及使用 1. tesseract 4.0 安装 安装包下载地址: http://digi.bib.uni-mannheim.de/tesseract/tesse ...
- 中文手写数据生成基于paddleocr和textrenderer-大幅提高中文识别准确率
文章目录 参考 一.textrenderer更多参数解释 二.准备手写字体文件 效果展示 参考 主要是参考了这位大佬的工作 ,大佬说生成都是灰度图,因为考虑样本多样性,主要介绍如何生成彩色图片,字典文 ...
- Tensorflow之基于MNIST手写识别的入门介绍
Tensorflow是当下AI热潮下,最为受欢迎的开源框架.无论是从Github上的fork数量还是star数量,还是从支持的语音,开发资料,社区活跃度等多方面,他当之为superstar. 在前面介 ...
最新文章
- Spring Boot 3.0 M1 发布,正式弃用 Java 8,最低要求 Java 17。。。
- 车道检测源码分析系列
- 手机浏览器不支持jquery_简洁清新实用适合做浏览器主页 支持手机浏览器
- 谈Elasticsearch下分布式存储的数据分布
- 【C++ grammar】对象指针、对象数组、函数参数
- 产品运营 跨境支付_餐饮网店的运营 跨境支付哪个平台最好
- java的课后作业咋写_写的简单的java第三季的课后作业
- Security Tutorials系列文章第七章:User-Based Authorization(下)
- python + opencv: 解决不能读取视频的问题
- Go Elasticsearch 查询快速入门
- python怎么使用base64_python常用库之base64
- spring boot+Quartz+数据库存储
- 安川机器人原点丢失_安川机器人原点及校准浅析
- hutool实战(带你掌握里面的各种工具)目录
- 3.取色精灵V2.0-非模态对话框自建消息队列、VS2008风格对话框、使用Common Controls、悬浮透明窗口、使用SLIDER控件
- IEEE邮件曝光,禁止华为员工审稿!
- 群晖DOCKER搭建自动签到 PT网站再也不怕忘记登录了
- 华为+android+root权限获取root,华为手机root权限获取方法
- eventscheduler mysql_Mysql 中的事件 事件调度器(Event Scheduler)
- 身份证ocr识别开源方案_多因素身份验证的开源替代方案:privacyIDEA