NEWS

新闻

了解openKylin最新资讯,关注社区和产品动态。

NEWS

Learn about the latest news.

【技术专栏】openKylin KART AI子系统入门——文字识别篇!

2025-12-03 09:41:47

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

KART.png

OpenAtom openKylin(简称“openKylin”)社区AISubsystem SIG组主导开发的KART(Kylin AI Runtime & Tensor) AI子系统——文字识别接口,秉承全场景适配、高性能处理、便捷集成的目标,为社区开发者打造了一套完整的图像文字提取工具集,帮助快速构建稳定可靠的文档数字化与图像内容分析应用!

核心能力:模块化接口设计,全链路流程覆盖

KART AI子系统文字识别接口聚焦“图像文字提取与位置信息分析”这个核心场景,采用模块化接口设计,覆盖模型配置(其中端侧模型目前仅支持KART AI子系统集成的模型)、文字识别结果解析全流程,主要体现在:

  • 图像文字识别:根据输入的图像文件或图像数据识别并提取其中的文字内容,生成对应的文本结果;

空白智能白板(1).png

  • 会话管理:实现文字识别会话的全生命周期管理,包括创建、初始化和销毁识别会话。通过会话机制管理识别过程中的资源和状态,确保识别任务的高效执行;

  • 异步结果回调:采用异步回调机制处理识别结果,避免阻塞主线程。支持注册自定义回调函数和用户数据,实现灵活的结果处理逻辑;

  • 文本位置信息获取:不仅提供识别出的文本内容,还能获取每行文字在图像中的精确位置坐标(四个角点信息),适用于需要位置信息的高级应用场景;

  • 多种输入格式支持:提供从图像文件路径和图像数据流两种方式输入,满足不同业务场景下的需求。文件路径方式适用于本地文件处理,数据流方式适用于网络传输或内存中的图像数据。

配置方式:下载即用,快速部署 对于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子系统的规划、维护和升级工作,主要项目仓库地址如下: