# 基于Tesseract-OCR的手写输入法程序 **Repository Path**: elephantsoft/Handwritten-input-method ## Basic Information - **Project Name**: 基于Tesseract-OCR的手写输入法程序 - **Description**: No description available - **Primary Language**: C/C++ - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2023-12-14 - **Last Updated**: 2023-12-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 基于Tesseract-OCR的手写输入法程序 #### 介绍 基于Tesseract-OCR开发的一款手写输入法程序,该程序用于国产化自助终端设备应用的文字输入,支持手写输入、英文输入、字符输入。 #### 实现功能 1、响应点击事件呼出界面 2、支持中文,字母,数字,字符的输入; 3、支持手写识别,具有联想功能 4、能实现光标跟随效果,即键盘界面随着用户点击位置发生变更,在用户输入框的最近位置显示输入法界面; #### 实现条件 开发环境:C/C++,QT 开发语言:C/C++ 实验平台:UOS操作系统 文字识别库:Tesseract-OCR 编译器:GCC,G++ #### 关键技术说明 1 输入法程序通过调用Tesseract库进行手写汉字的识别。 Tesseract是一款开源的OCR框架,可以用于文字识别,该框架提供的中文字库对于手写汉字的识别准确率不高,可以通过训练字库来提高手写汉字的识别准确率。 2 利用D-Bus进行进程间通信实现响应点击事件呼出界面和光标追随效果 D-Bus是一种进程间通信的机制。通常,Linux发行版都会提供两种Message Bus:System Bus和Session Bus。System Bus主要用于内核和一些系统全局的service之间通信;Session Bus 主要用于桌面应用程序之间的通信。 D-Bus中用于通信的基本单元叫做Message,当应用程序连接到Message Bus上时,D-Bus会分配一个unique connection name,这个unique name通常的格式如":34-907"。应用程序还可以向Message Bus请求一个well-known name,例如"com.mycompany.myapp”。当一个应用程序连接到Message Bus上时,可以拥有两种名称:unique connection name和well-known name。这两种名称的关系可以理解为网络上的IP地址和域名的关系。 #### 设计结构 项目分为三大结构:1输入法程序;2输入法插件;3输入法测试程序 输入法程序主要负责的是显示输入法界面以及手写汉字的识别; 输入法测试程序主要用于显示输入结果; 输入法插件负责的是输入法测试程序与输入法程序两个进程间的通信。 #### 功能模块说明 1 输入法程序 利用Qt Creator编写输入法程序的主界面,通过调用Tesseract库实现对手写汉字的识别,同时也实现了数字,字母及字符的输入和删除操作。 输入法界面要在dbus上注册一个服务和对象,这个对象就是输入法界面,dbus上有了这个服务,应用程序才能通过dbus和输入法界面对话。注册服务和对象的代码如下: InputService::InputService(QObject *object) { QDBusConnection connect = QDBusConnection::sessionBus(); if (!connect.registerService("com.mh.input")) { qFatal("Unable to register at DBus"); return; } qDebug() << "register servece" << endl; if (!connect.registerObject("/input/vkim", object, QDBusConnection::ExportAllSignals | QDBusConnection::ExportAllSlots)) { qFatal("Unable to register object at DBus"); return; } qDebug() << "register object" << endl; } InputService::~InputService() { QDBusConnection connect = QDBusConnection::sessionBus(); connect.unregisterObject("/input/vkim"); qDebug() << "unregister object" << endl; connect.unregisterService("com.mh.input"); qDebug() << "unregister servece" << endl; } 其中keyboard就是键盘界面,这样就把键盘对象注册到了dbus上,其中com.mh.input是服务名,/input/vkim是该服务下的路径,另外还会生成一个接口的名字叫local.keyboard.Dialog,其中keyboard是程序的名字,Dialog是注册对象的类型 2 输入法插件 利用dbus实现输入法测试程序与输入法程序两个进程间的通信,部分代码如下 VkImPlatformInputContext::VkImPlatformInputContext() : focusObject(NULL) { dbusInterface = new QDBusInterface("com.mh.input", "/input/vkim", "local.keyboard.Dialog", QDBusConnection::sessionBus(), this); connect(dbusInterface, SIGNAL(commit(QString)), SLOT(keyboardCommit(QString))); } void VkImPlatformInputContext::showInputPanel() { if (dbusInterface != NULL) { QWidget *w = qobject_cast(focusObject); QPoint pt = w->pos(); QRect rect = w->rect(); pt = w->mapToGlobal(QPoint(0, 0)); int x = pt.x(); int y = pt.y(); dbusInterface->call("showKeyboard", pt, rect); } else { qDebug() << "interface is null" << endl; } } 其中dbus的接口要跟输入法界面注册的接口一致,focusObject就是当前输入框的焦点控件。插件通过dbus的call函数就可以调用输入法界面导出的槽函数了。那showInputPanel又是谁来调用的呢?这是由QGuiApplication::inputMethod()来调用的,在qlineedit.cpp文件中的mouseReleaseEvent函数中,可以看到调用了handleSoftwareInputPanel,这个是qwidget_p.h中的函数,因为QLineEditPrivate继承了QWidgetPriave,可以看到handleSoftwareInputPanel函数调用了QGuiApplication::inputMethod()->show();而这个输入法实际上只是一个接口,他调用的还是插件里的show函数,platform在初始化的时候创建了一个platform_integration,就叫它平台集成吧,这平台集成里有各种各样与平台相关的东西,输入法插件就是其中一个,输入法就是从平台集成中获取到了inputContext也就是我们创建的插件。