当前位置: 首页 > article >正文

如何使用tesseract的C++接口做字符识别

要从图片中识别字符,可以使用tesseract库。

如果使用Python,可以直接使用

pip install tesseract

安装之后,就可以在Python中

import tesseract

来使用了。

如果我们在C++的开发中,要使用tesseract,其实也非常简单。

tesseract在Linux各发行版,都有现成的二进制安装包,而且还同时提供了C语言、C++的支持。本文中的示例,采用C++的接口。

开发环境

如果是Fedora系统,可以直接通过

dnf install tesseract-devel

来安装tesseract的开发库。

之后,可以直接在程序中链接-ltesseract,包含的头文件目录除了/usr/include/tesseract之外,还需要/usr/include/leptonica、/usr/include/libpng16等。

为了简化这一操作,可以使用pkg-config文件。

如:

~/$ pkg-config --cflags --libs tesseract
-I/usr/include/leptonica -I/usr/include/libpng16 -DWITH_GZFILEOP -I/usr/include/webp -ltesseract

头文件以及API

安装好tesseract,在构建系统中设置包含目录之后,就可以在程序中包含相应的头文件了。

如果是在C语言中,需要包含

#include <tesseract/capi.h>

,而如果是在C++中,可以使用C语言的API,也可以使用C++的Class API,需要包含:

#include <tesseract/baseapi.h>

使用这个头文件的话,使用的是tesseract的命名空间之中的TessBaseAPI。

如果我们打开tesseract/baseapi.h,可以看到TessBaseAPI的方法很多。但是,其实我们做OCR核心要使用的却并不多,基本上就Init、SetImage与GetUTF8Text这样三个就可以了。

  • 构造函数
76 class TESS_API TessBaseAPI {  
77 public:  
78   TessBaseAPI();  
79   virtual ~TessBaseAPI();  
80   // Copy constructor and assignment operator are currently unsupported.  
81   TessBaseAPI(TessBaseAPI const &) = delete;  
82   TessBaseAPI &operator=(TessBaseAPI const &) = delete;  

构造函数没有参数,不支持复制,非常简单。

  • 版本号
84   /**  
85    * Returns the version identifier as a static string. Do not delete.  
86    */  
87   static const char *Version();

一个静态方法,返回API的版本,可以根据不同的版本做条件开发。

  • 初始化设置
97   int Init(const char *datapath, const char *language, OcrEngineMode mode,  
198            char **configs, int configs_size,  
199            const std::vector<std::string> *vars_vec,  
200            const std::vector<std::string> *vars_values,  
201            bool set_only_non_debug_params);  
202   int Init(const char *datapath, const char *language, OcrEngineMode oem) {  
203     return Init(datapath, language, oem, nullptr, 0, nullptr, nullptr, false);  
204   }  
205   int Init(const char *datapath, const char *language) {  
206     return Init(datapath, language, OEM_DEFAULT, nullptr, 0, nullptr, nullptr,  
207                 false);  
208   }  
209   // In-memory version reads the traineddata file directly from the given  
210   // data[data_size] array, and/or reads data via a FileReader.  
211   int Init(const char *data, int data_size, const char *language,  
212            OcrEngineMode mode, char **configs, int configs_size,  
213            const std::vector<std::string> *vars_vec,  
214            const std::vector<std::string> *vars_values,  
215            bool set_only_non_debug_params, FileReader reader);  
216

Init方法的目的是初始化语言支持,比如是识别英语,还是汉语,重载版本比较多。

但是,如果开发简单的应用,使用最简单的

int Init(const char *datapath, const char *language)

重载版本就可以了。

而且,datapath都可以简单地设置为nullptr,指的是使用默认的路径,在我的Fedora 41系统上,这个目录是/usr/share/tesseract/testdata。

这个目录里面有:

ls /usr/share/tesseract/tessdata/  
chi_sim.traineddata  chi_sim_vert.traineddata  configs  eng.traineddata  tessconfigs

我们要识别什么语言,就要加载相应的.traineddata文件。所以,后面的language需要设置.traineddata前面的部分。

比如,我们要识别英语,就使用:

TessBaseAPI baseapi;
baseapi.Init (nullptr, "eng");

如果要识别多种语言,就使用+连接起来。如我们要识别英语与简体中文,就使用:

TessBaseAPI baseapi;
baseapi.Init (nullptr, "eng+chi_sim");

根据头文件里注释,Init()这个方法可以调用多次,在运行中动态更改识别的语言。

  • 设置图片数据
307   void SetImage(const unsigned char *imagedata, int width, int height,
308                 int bytes_per_pixel, int bytes_per_line);
309 

设置图片的数据指针,之后是图片的宽、长、以及每个像素的字节数,最后是每一行的字节数。一般来说,最后一个参数可以通过宽度以及每个像素的字节数相乘计算出来,但是因为图片数据往往会做填充,所以每行字节数就需要单独指定。

  • 设置识别范围
void SetRectangle(int left, int top, int width, int height);

设置图片以后,使用这个方法可以设置一下识别的范围。一般需要识别图片中的一个矩形框的时候使用,如果识别整个图片可以不设。

  • 识别字符
char *GetUTF8Text();

做字符识别最核心的方法,返回的是一个UTF-8编码的字节数组。

注意:这个返回的字节数组,需要调用者手动释放。

  • 清除临时数据
void Clear();

这个方法是用来清理图片数据的。调用这个函数之后,就不能再做任何与前面设置过的图片相关的操作了。

  • 结束
void End();

跟Init()配对使用,用于把临时数据都清理干净。

示例

下面这块代码,可以对一张输入图片,识别字符,之后保存到剪贴板里。

#include <QApplication>  
#include <QClipboard>  
#include <QImage>  
#include <QPixmap>  
  
#include <memory>  
#include <tesseract/baseapi.h>  
  
using namespace std;  
using namespace tesseract;  
  
std::unique_ptr<char>  
getTextFromPixmap(const QPixmap &pixmap) {  
  auto api = TessBaseAPI{};  
  api.Init(nullptr, "eng+chi_sim");  
  auto image = pixmap.toImage();  
  image = image.convertToFormat(QImage::Format_RGB888);  
  api.SetImage(image.bits(), image.width(), image.height(), 3,  
               static_cast<int>(image.bytesPerLine()));  
  auto text = api.GetUTF8Text();  
  api.Clear();  
  api.End();  
  return unique_ptr<char>(text);  
}  
  
int  
main(int argc, char *argv[]) {  
  Q_ASSERT(argc > 1);  
  QApplication app{argc, argv};  
  auto pixmap = QPixmap(argv[1]);  
  auto text = getTextFromPixmap(pixmap);  
  if (text) {  
    qInfo() << "get :" << text.get() << " from " << argv[1];  
    auto clipboard = QApplication::clipboard();  
    clipboard->setText(text.get());  
  } else {  
    qCritical() << "get nothing from " << argv[1];  
  }  
}

http://www.kler.cn/a/405324.html

相关文章:

  • 解决IDEA报包不存在,但实际存在的问题
  • MyBatis的resultType和resultMap区别
  • Keil+VSCode优化开发体验
  • AI一键生成原创花卉印花图案——创新与效率的结合
  • Makefile 之 自动化变量
  • 【C++】深入解析 C++ 多态机制:虚函数、动态绑定与抽象类的精髓
  • 一文详细了解websocket应用以及连接断开的解决方案
  • 【Kafka 实战】Kafka 如何保证消息的顺序性?
  • C/C++语言基础--C++检测内存泄露方法、RALL思想模型
  • RTPS通信使用的socket和端口
  • 从零开始:如何使用第三方视频美颜SDK开发实时直播美颜平台
  • 在 Swift 中实现字符串分割问题:以字典中的单词构造句子
  • 摸一下elasticsearch8的AI能力:语义搜索/vector向量搜索案例
  • GPU服务器厂家:为什么要选择 GPU 服务器?
  • 包装器与绑定器
  • 06、Spring AOP
  • Bug Fix 20241122:缺少lib文件错误
  • 低速接口项目之串口Uart开发(四)——UART串口实现FPGA内部AXILITE寄存器的读写控制
  • 历遍单片机下的IIC设备[ESP--0]
  • 浅谈新能源光储充一体化电站设计方案
  • PyTorch图像预处理:计算均值和方差以实现标准化
  • 网安基础知识|IDS入侵检测系统|IPS入侵防御系统|堡垒机|VPN|EDR|CC防御|云安全-VDC/VPC|安全服务
  • RocketMQ文件刷盘机制深度解析与Java模拟实现
  • Leecode刷题C语言之统计不是特殊数字的数字数量
  • xbh的比赛
  • Qt 的事件投递机制:从基础到实战