Expose the PP-OCRv6 engine through a stable C ABI and installable shared and static libraries, plus a ctypes Python package that follows the RapidOCR call shape. Keep AVX-512 out of the AVX2 object file and speed up GEMM accumulate and the AArch64 GEMM tile. Co-authored-by: Daniel <znsoft@163.com>
4.8 KiB
C, C++, and Python API
The inference core is unchanged: a built-in PP-OCRv6 ONNX interpreter with CPU and optional Vulkan execution. This document is the public surface other programs should call.
Build and install
git submodule update --init --recursive
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
cmake --install build --prefix "$PWD/install"
That produces:
libppocr.a(ppocr::static)libppocr.so(ppocr::ppocr), SONAMElibppocr.so.5- headers under
include/ppocr/ lib/cmake/ppocr/ppocrConfig.cmake
find_package(ppocr REQUIRED)
target_link_libraries(app PRIVATE ppocr::ppocr) # shared
# or ppocr::static
PPOCR_BUILD_SHARED and PPOCR_BUILD_STATIC both default to ON.
Vulkan shaders are embedded only when a host glslangValidator (or the
vendored Windows glslang.exe on Windows) is available. The CPU engine does
not need them.
Examples:
./build/ppocr_c_api_demo det.onnx rec.onnx dict.txt image.ppm
./build/ppocr_cpp_api_demo det.onnx rec.onnx dict.txt image.ppm
./build/ppocr_c_api_demo --cpu-info
Images passed to the library are packed RGB, row-major, 8-bit. ppocr_load_ppm
reads binary P6 PPM. JPEG/PNG decoding stays in the application (or in the
Python package, which uses Pillow).
C ABI
include/ppocr/ppocr.h is a stable C ABI:
extern "C"- opaque
ppocr_ocr* - plain structs for options, images, and text boxes
- integer status codes (
PPOCR_OK,PPOCR_ERR_*) ppocr_create/ppocr_destroy,ppocr_result_free,ppocr_image_free- thread-local
ppocr_last_error() ppocr_options.struct_sizeso new fields can be appended
ppocr_options_init fills the same defaults as ppocr::Options. One handle
must not be used from two threads at once. ppocr_recognize_batch preserves
input order.
Runtime CPU selection is reported by ppocr_query_cpu_info. active_isa is
avx512, avx2, neon, or scalar. See docs/PERFORMANCE.md for the rule
that keeps AVX-512 instructions out of an AVX2-only process.
C++ API
include/ppocr/ppocr.hpp is the C++ API already used by the in-tree tools:
ppocr::Options options;
options.backend = ppocr::Backend::cpu_only;
ppocr::OCR ocr(det_path, rec_path, dict_path, options);
for (const ppocr::Result& result : ocr.Recognize(ppocr::LoadPPM(path))) {
// result.text, result.confidence, result.bbox, result.box
}
QueryCpuInfo() and SetDetectionThresholds() are part of that header.
Exceptions use std::runtime_error. The C ABI catches them.
Python package
The package name and call shape follow main:
from rapidocr import RapidOCR, EngineType, ModelType, OCRVersion
engine = RapidOCR(params={
"Det.model_path": "PP-OCRv6_det_tiny.onnx",
"Rec.model_path": "PP-OCRv6_rec_tiny.onnx",
"Rec.rec_keys_path": "ppocrv6_tiny_dict.txt",
"Det.model_type": ModelType.TINY,
"Rec.model_type": ModelType.TINY,
"Det.ocr_version": OCRVersion.PPOCRV6,
"Global.text_score": 0.5,
"Global.use_cls": False,
})
result = engine("page.png", box_thresh=0.5, unclip_ratio=1.6)
result.txts
result.scores
result.boxes # float32 array, shape (N, 4, 2), TL TR BR BL
result.elapse # seconds
result.to_json()
result.to_markdown()
result.vis("vis.png")
params keys use the same Section.name form as main (Det.box_thresh,
Global.text_score, Rec.rec_batch_num, ...). A YAML config_path is
loaded with PyYAML and then overridden by params.
File paths, URLs, bytes, and PIL images are decoded as RGB. A numpy ndarray
is treated as BGR, which is what main does for cv2 images, and converted
to RGB before the native engine.
Binding choice
Python calls the C ABI with ctypes. One shared library is the contract for C, for other FFI languages, and for Python, so the result struct cannot drift from a second pybind11 wrapper. scikit-build-core still builds that library into a wheel:
pip install ./python
What does not match main
main |
this package |
|---|---|
| ONNX Runtime, OpenVINO, Paddle, PyTorch, TensorRT, MNN | built-in PP-OCRv6 interpreter only (EngineType.ONNXRUNTIME or EngineType.PPOCR_CPP) |
| PP-OCRv4 and v5 model zoo | PP-OCRv6 ONNX detector + recognizer |
angle classifier (use_cls=True by default) |
flag is accepted and ignored, with one warning |
use_det=False / use_rec=False |
raises RapidOCRError |
| word and character boxes | return_word_box warns; word_results is empty |
elapse_list is [det, cls, rec] |
[None, None, total] because the native call is one timed region |
OpenCV drawing in vis |
Pillow polygons |
result.txts, result.scores, and result.boxes stay the fields existing
callers read. text_score, box_thresh, and unclip_ratio still filter or
retune a call without rebuilding the models.