【技术专栏】openKylin KART AI子系统入门——文字识别篇!
在数字化浪潮推动下,快速准确地从图像中提取文字信息已成为众多行业的迫切需求。无论是档案管理、证件识别还是自动化办公,专业的文字识别技术都能极大提升文档处理效率。

OpenAtom openKylin(简称“openKylin”)社区AISubsystem SIG组主导开发的KART(Kylin AI Runtime & Tensor) AI子系统——文字识别接口,秉承全场景适配、高性能处理、便捷集成的目标,为社区开发者打造了一套完整的图像文字提取工具集,帮助快速构建稳定可靠的文档数字化与图像内容分析应用!
核心能力:模块化接口设计,全链路流程覆盖
KART AI子系统文字识别接口聚焦“图像文字提取与位置信息分析”这个核心场景,采用模块化接口设计,覆盖模型配置(其中端侧模型目前仅支持KART AI子系统集成的模型)、文字识别、结果解析全流程,主要体现在:
- 图像文字识别:根据输入的图像文件或图像数据识别并提取其中的文字内容,生成对应的文本结果;

会话管理:实现文字识别会话的全生命周期管理,包括创建、初始化和销毁识别会话。通过会话机制管理识别过程中的资源和状态,确保识别任务的高效执行;
异步结果回调:采用异步回调机制处理识别结果,避免阻塞主线程。支持注册自定义回调函数和用户数据,实现灵活的结果处理逻辑;
文本位置信息获取:不仅提供识别出的文本内容,还能获取每行文字在图像中的精确位置坐标(四个角点信息),适用于需要位置信息的高级应用场景;
多种输入格式支持:提供从图像文件路径和图像数据流两种方式输入,满足不同业务场景下的需求。文件路径方式适用于本地文件处理,数据流方式适用于网络传输或内存中的图像数据。
配置方式:下载即用,快速部署 对于openKylin 2.0 SP2 版本,默认已集成KART AI子系统。对于openKylin 2.0 SP1或者更早的版本,则需要手动安装AI子系统,安装步骤如下:
步骤 1:添加proposed源,将以下源添加到/etc/apt/sources.list文件中:
deb http://archive.build.openkylin.top/openkylin/ nile-proposed main cross pty
步骤 2:启动命令行工具,执行如下安装命令后重启机器:
sudo apt update && apt install kylin-ai-subsystem-plugin kylin-ai-subsystem
KART AI子系统安装就绪后,下载开发包即可使用文字识别SDK:
sudo apt install libkysdk-coreai-vision-dev
KART文字识别接口使用示例
使用该API接口需先创建会话实例,若初始化失败,接口将立即返回具体错误码。初始化成功后,设置结果回调函数即可调用业务接口。每个会话一次仅处理一个任务,多任务自动串行执行;如需并发,可创建多个会话。若初始化失败,处理错误后需重新初始化。具体步骤如下:
步骤 1:配置 CMakeLists.txt
find_package(PkgConfig REQUIRED)
pkg_check_modules(KYSDK_AI_VISION kysdk-coreai-vision)
include_directories(${KYSDK_AI_VISION_INCLUDE_DIRS})
target_link_libraries(
XXXX
${KYSDK_AI_VISION_LIBRARIES}
)步骤 2:回调函数设置
void callback(TextRecognitionResult *result, void *user_data) {
// 开始打印识别结果
fprintf(stdout, "Start printing results.\n");
// 初始化变量,用于存储文本行数和角点数量
int text_line_num = 0, points_num = 0;
// 打印识别出的完整文本内容
fprintf(stdout, "text : %s\n",
text_recognition_result_get_value(result));
// 打印错误码,0表示无错误
fprintf(stdout, "err code : %i\n",
text_recognition_result_get_error_code(result));
// 打印错误信息,无错误时为空字符串
fprintf(stdout, "err message : %s\n",
text_recognition_result_get_error_message(result));
// 获取识别结果中的所有文本行
TextLine **text_line =
text_recognition_result_get_text_lines(result, &text_line_num);
// 检查文本行数据是否有效
if (text_line == nullptr) {
fprintf(stderr, "The result is invalid, please check image\n");
return;
}
// 遍历每一行文本
for (int i = 0; i < text_line_num; ++i) {
// 获取当前行文本的四个角点坐标
PixelPoint *point =
text_line_get_corner_points(text_line[i], &points_num);
// 检查角点数据是否有效
if (point == nullptr) {
fprintf(stderr, "No point\n");
return;
}
// 打印当前行的文本内容
fprintf(stdout, "The %i line text: %s\n", i,
text_line_get_value(text_line[i]));
// 打印当前行文本的四个角点坐标
for (int j = 0; j < points_num; j++) {
fprintf(stdout, "The corner points text %d: (%d, %d)\n",
j, point[j].x, point[j].y);
}
// 处理用户自定义数据
if (user_data != nullptr) {
// 将用户数据转换为字符串并打印
const char *user_data_str = static_cast(user_data); fprintf(stdout, "%s\n", user_data_str); } else { // 用户数据为空时的提示信息 fprintf(stdout, "user data is nullptr\n"); } // 完成结果打印 fprintf(stdout, "Printing result completed.\n");
}步骤 3:从图片路径进行文字识别
#include<coreai/vision/textrecognition.h>
#include<gio/gio.h>
#include<gio/giotypes.h>
#include<iostream>
// 配置图像路径
const char *TEST_FILE_PATH = "/path/to/image";
void test_ocr_from_file() {
// 定义用户自定义数据,将在回调函数中使用
const char *user_data = "Test coreai vision from image file\n";
// 创建文字识别会话实例
TextRecognitionSession *session = text_recognition_create_session();
if (session == nullptr) {
std::cerr << "Failed to create text recognition session" << std::endl;
return;
}
// 初始化会话
int init_result = text_recognition_init_session(session);
if (init_result != 0) {
std::cerr << "Failed to initialize session, error code: " << init_result << std::endl;
text_recognition_destroy_session(&session);
return;
}
// 设置文本识别callback,识别结果会通过callback返回
text_recognition_result_set_callback(session, callback, (void *)user_data);
// 异步执行文字识别任务,从指定图像文件中识别文本
text_recognition_recognize_text_from_image_file_async(session,TEST_FILE_PATH);
// 创建并运行主事件循环,等待异步操作完成
GMainLoop *main_loop = g_main_loop_new(nullptr, false);
if (main_loop == nullptr) {
std::cerr << "Failed to create main loop" << std::endl;
text_recognition_destroy_session(&session);
return;
}
g_main_loop_run(main_loop);
// 识别完毕后,提示用户输入回车来退出程序
std::cout << "Press Enter to quit..." << std::endl;
while (std::getchar() != '\n') {
}
// 清理资源,销毁会话
text_recognition_destroy_session(&session);
// 退出并释放主事件循环资源
g_main_loop_quit(main_loop);
g_main_loop_unref(main_loop);
}步骤 4:从图像数据进行文字识别
#include<coreai/vision/textrecognition.h>
#include<gio/gio.h>
#include<gio/giotypes.h>
#include<filesystem>
#include<fstream>
#include<iostream>
#include<vector>
// 配置图像路径
const char *TEST_FILE_PATH = "/path/to/imagedata";
// 从指定路径读取图像文件数据到内存缓冲区
std::vector<char> read_image_data(const std::string &file_path) {
// 以二进制模式打开文件
std::ifstream file(file_path, std::ios::binary);
if (!file.is_open()) {
// 文件打开失败,输出错误信息
fprintf(stderr, "Failed to open file: %s\n", file_path.c_str());
return {};
}
// 获取文件大小
file.seekg(0, std::ios::end);
std::streampos file_size = file.tellg();
file.seekg(0, std::ios::beg);
// 分配内存并读取文件内容
std::vector<char> image_data(file_size);
file.read(image_data.data(), file_size);
return image_data;
}
void test_ocr_from_data() {
// 使用std::filesystem检查文件是否存在
namespace fs = std::filesystem;
if (!fs::exists(TEST_FILE_PATH)) {
// 文件不存在,输出错误信息
fprintf(stderr, "error\n");
return;
}
// 定义用户自定义数据,将在回调函数中使用
const char *user_data = "Test coreai vision from image file\n";
// 读取图像文件数据到内存
const std::vector<char> image_data = read_image_data(TEST_FILE_PATH);
// 创建文字识别会话实例
TextRecognitionSession *session = text_recognition_create_session();
if (session == nullptr) {
std::cerr << "Failed to create text recognition session" << std::endl;
return;
}
// 初始化会话
int init_result = text_recognition_init_session(session);
if (init_result != 0) {
std::cerr << "Failed to initialize session, error code: "
<< init_result << std::endl;
text_recognition_destroy_session(&session);
return;
}
// 设置文本识别callback,识别结果会通过callback返回
text_recognition_result_set_callback(session, callback, (void *)user_data);
// 异步执行文字识别任务,从内存数据中识别文本
text_recognition_recognize_text_from_image_data_async(
session, image_data.data(), image_data.size());
// 创建并运行主事件循环,等待异步操作完成
GMainLoop *main_loop = g_main_loop_new(nullptr, false);
if (main_loop == nullptr) {
std::cerr << "Failed to create main loop" << std::endl;
text_recognition_destroy_session(&session);
return;
}
g_main_loop_run(main_loop);
// 识别完毕后,提示用户输入回车来退出程序
std::cout << "Press Enter to quit..." << std::endl;
while (std::getchar() != '\n') {
}
// 清理资源,销毁会话
text_recognition_destroy_session(&session);
// 退出并释放主事件循环资源
g_main_loop_quit(main_loop);
g_main_loop_unref(main_loop);
}关于AISubsystem SIG
openKylin社区AISubsystem SIG小组致力于openKylin KART AI子系统的规划、维护和升级工作,主要项目仓库地址如下: