{"id":21802455,"url":"https://github.com/qengineering/paddleocr-lite-document","last_synced_at":"2026-03-03T05:39:52.722Z","repository":{"id":157547529,"uuid":"624874261","full_name":"Qengineering/PaddleOCR-Lite-Document","owner":"Qengineering","description":"PaddleOCR Lite document scanner on bare Raspberry Pi 4","archived":false,"fork":false,"pushed_at":"2024-06-10T06:59:07.000Z","size":3159,"stargazers_count":27,"open_issues_count":1,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-27T09:23:00.107Z","etag":null,"topics":["cpp","deep-learning","ocr","ocr-recognition","opencv4","optical-character-recognition","paddle-lite","paddlelite","paddleocr","raspberry-pi-4","raspberry-pi-64-os"],"latest_commit_sha":null,"homepage":"https://qengineering.eu/install-paddle-lite-on-raspberry-pi-4.html","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Qengineering.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-07T13:25:08.000Z","updated_at":"2025-02-19T07:42:18.000Z","dependencies_parsed_at":"2024-01-17T18:31:35.942Z","dependency_job_id":"e462fa99-e6a6-4c89-9813-1bc58c89d5c6","html_url":"https://github.com/Qengineering/PaddleOCR-Lite-Document","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Qengineering%2FPaddleOCR-Lite-Document","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Qengineering%2FPaddleOCR-Lite-Document/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Qengineering%2FPaddleOCR-Lite-Document/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Qengineering%2FPaddleOCR-Lite-Document/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Qengineering","download_url":"https://codeload.github.com/Qengineering/PaddleOCR-Lite-Document/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248764385,"owners_count":21158075,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","deep-learning","ocr","ocr-recognition","opencv4","optical-character-recognition","paddle-lite","paddlelite","paddleocr","raspberry-pi-4","raspberry-pi-64-os"],"created_at":"2024-11-27T11:28:46.634Z","updated_at":"2026-03-03T05:39:47.692Z","avatar_url":"https://github.com/Qengineering.png","language":"C++","readme":"# PaddleOCR Lite document scanner\n![output image]( https://qengineering.eu/github/WillekePassOut.webp )\u003cbr\u003e\n_Image source: [Dutch  government](https://www.rijksoverheid.nl/actueel/nieuws/2021/08/02/nieuw-model-nederlandse-identiteitskaart-per-2-augustus-2021)._\u003cbr\u003e\u003cbr\u003e\n[![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)\u003cbr/\u003e\u003cbr/\u003e\nPaper: [E-book: _Dive Into OCR_ (PDF)](https://paddleocr.bj.bcebos.com/ebook/Dive_into_OCR.pdf)\u003cbr/\u003e\u003cbr/\u003e\nPaddleOCR is a text engine. It can detect text in a scene, determine the orientation, and recognize the characters (Chinese or Latin).\u003cbr\u003e\nTo do so, it needs a deep learning framework, like PaddlePaddle or Paddle-Lite.\u003cbr\u003e\nThis application uses Paddle-Lite because, as the name already suggests, it is a lightweight version of PaddlePaddle, it can deploy small quantized models (INT8), and its architecture is well suited for the ARMv8 processors found on a Raspberry Pi.\u003cbr\u003e\nOnce all the software is installed, it can run on a bare Raspberry Pi without needing cloud services or any (expensive) license.\u003cbr\u003e\u003cbr\u003e\nInference time (RPi 4 @ 1925 MHz - 64 bits Bullseye OS):\u003cbr\u003e\nDetect text: 366 mSec.\u003cbr\u003e\nRecognize text: 134 mSec per line.\u003cbr\u003e\u003cbr\u003e\nInference time (**RPi 5** @ 2450 MHz - 64 bits Bookworm OS):\u003cbr\u003e\nDetect text: 183 mSec.\u003cbr\u003e\nRecognize text: 67 mSec per line.\u003cbr\u003e\u003cbr\u003e\nSpecial made for a bare Raspberry Pi 4, see [Q-engineering deep learning examples](https://qengineering.eu/deep-learning-examples-on-raspberry-32-64-os.html)\n\n------------\n\n## Dependencies.\nTo run the application, you have to:\n- A raspberry Pi 4 with a 32 or 64-bit operating system. It can be the Raspberry 64-bit OS, or Ubuntu 18.04 / 20.04. [Install 64-bit OS](https://qengineering.eu/install-raspberry-64-os.html) \u003cbr/\u003e\n- PaddleOCR installed.\n- Paddle-Lite optimizer. [Install Paddle-Lite](https://qengineering.eu/install-paddle-lite-on-raspberry-pi-4.html) \u003cbr/\u003e\n- OpenCV 64-bit installed. [Install OpenCV 4.5](https://qengineering.eu/install-opencv-4.5-on-raspberry-64-os.html) \u003cbr/\u003e\n- Code::Blocks installed. (```$ sudo apt-get install codeblocks```)\n\n------------\n\n## Installing the app.\nBefore you can run the application, you need to install quite a lot of software. Let's start.\n#### OpenCV\nThe first package you need is OpenCV. On our website, there are [several guides](https://qengineering.eu/install-opencv-4.5-on-raspberry-64-os.html) on how to install OpenCV on your Raspberry Pi.\u003cbr\u003e\nIt shouldn't be a problem if you follow the instructions carefully.\n#### Code::Blocks\nFor compilation, you can choose between CMake or Code::Blocks.\nWe find Code::Blocks more comfortable to work with than CMake because of its IDE, which allows quick changes.\n```\n$ sudo apt-get install codeblocks\n```\n#### Paddle-Lite framework\nIt's time to install the Paddle-Lite framework. See also our [guide](https://qengineering.eu/install-paddle-lite-on-raspberry-pi-4.html).\n```\n# install dependencies\n$ sudo apt-get install cmake wget\n# download Paddle Lite\n$ git clone --depth=1 https://github.com/PaddlePaddle/Paddle-Lite.git\n$ cd Paddle-Lite\n# build 64-bit Paddle Lite (±1 hour)\n$ ./lite/tools/build_linux.sh --arch=armv8 --with_extra=ON --with_cv=ON --with_static_lib=ON\n# Once built, you will have the following directories:\nPaddle-Lite/inference_lite_lib.android.armv8/\n├── cxx                                        C++ prebuild library\n|   ├── include                                C++\n|   |   ├── paddle_api.h\n|   |   ├── paddle_image_preprocess.h\n|   |   ├── paddle_lite_factory_helper.h\n|   |   ├── paddle_place.h\n|   |   ├── paddle_use_kernels.h\n|   |   ├── paddle_use_ops.h\n|   |   └── paddle_use_passes.h\n|   └── lib                                           C++ library\n|       ├── libpaddle_api_light_bundled.a             C++ static library\n|       └── libpaddle_light_api_shared.so             C++ dynamic library\n\n# copy the headers and library to /usr/local/\n$ sudo mkdir -p /usr/local/include/paddle-lite\n$ sudo cp -r build.lite.linux.armv8.gcc/inference_lite_lib.armlinux.armv8/cxx/include/*.* /usr/local/include/paddle-lite\n$ sudo mkdir -p /usr/local/lib/paddle-lite\n$ sudo cp -r build.lite.linux.armv8.gcc/inference_lite_lib.armlinux.armv8/cxx/lib/*.* /usr/local/lib/paddle-lite\n```\n#### Paddle-Lite optimizer\nIn addition to the Paddle-Lite library, we also need the optimization tool `opt`.\u003cbr\u003e\nThe models used by PaddleOCR must match the version of the Paddle-Lite framework. No doubt Paddle-Lite will evolve, and the models provided here will no longer match the newer version.\u003cbr\u003e\u003cbr\u003e\n**👉 Please check issue https://github.com/Qengineering/PaddleOCR-Lite-Document/issues/1 for more info and recent solutions! 👈** \u003cbr\u003e\u003cbr\u003e\nBefore you can compile the optimizer, please check [pull requist #10164](https://github.com/PaddlePaddle/Paddle-Lite/pull/10164).\u003cbr\u003e\nThe `Paddle-Lite/lite/tools/build_linux.sh` need to be adapted for the aarch64 OS.\u003cbr\u003e\u003cbr\u003e\n![output image](https://qengineering.eu/github/Paddle_issue_10102.png)\u003cbr\u003e\u003cbr\u003e\nPerhaps, in the near future, the pull request was granted. Until that moment, please alter the `Paddle-Lite/lite/tools/build_linux.sh` file according to the suggestions above.\u003cbr\u003e\nWith the `build_linux.sh` script up to date, you can buid the optimizer with the following commands.\n```\n$ cd Paddle-Lite\n$ ./lite/tools/build_linux.sh --arch=armv8 --with_extra=ON --with_cv=ON build_optimize_tool\n# Once build, you will find the tool here: Paddle-Lite/build.opt/lite/api/opt\n```\nIntroduction to paddle_lite_opt parameters:\n\n|Options|Description|\n|---|---|\n|--model_dir|The path of the PaddlePaddle model to be optimized (non-combined form)|\n|--model_file|The network structure file path of the PaddlePaddle model (combined form) to be optimized|\n|--param_file|The weight file path of the PaddlePaddle model (combined form) to be optimized|\n|--optimize_out_type|Output model type, currently supports two types: protobuf and naive_buffer, among which naive_buffer is a more lightweight serialization/deserialization implementation. If you need to perform model prediction on the mobile side, please set this option to naive_buffer. The default is protobuf|\n|--optimize_out|The output path of the optimized model|\n|--valid_targets|The executable backend of the model, the default is arm. Currently it supports x86, arm, opencl, npu, xpu, multiple backends can be specified at the same time (separated by spaces), and Model Optimize Tool will automatically select the best method. If you need to support Huawei NPU (DaVinci architecture NPU equipped with Kirin 810/990 Soc), it should be set to npu, arm|\n|--record_tailoring_info|When using the function of cutting library files according to the model, set this option to true to record the kernel and OP information contained in the optimized model. The default is false|\n\n#### PaddleOCR models\nThe next step is getting the deep learning models PaddleOCR will be using.\u003cbr\u003e\nMostly you use three models: one for detecting the text, one for the orientation of the text and one for character recognition.\u003cbr\u003e\n\n```\n$ cd Paddle-Lite/build.opt/lite/api\n\n# Download the Chinese and English inference model of PP-OCRv3\n$ wget  https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_det_slim_infer.tar\n$ wget  https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_rec_slim_infer.tar\n$ wget  https://paddleocr.bj.bcebos.com/dygraph_v2.0/slim/ch_ppocr_mobile_v2.0_cls_slim_infer.tar\n\n#unzip the models\n$ tar xf  ch_PP-OCRv3_det_slim_infer.tar\n$ tar xf  ch_PP-OCRv3_rec_slim_infer.tar\n$ tar xf  ch_ppocr_mobile_v2.0_cls_slim_infer.tar\n\n# Convert detection model\n./opt --model_file=./ch_PP-OCRv3_det_slim_infer/inference.pdmodel  --param_file=./ch_PP-OCRv3_det_slim_infer/inference.pdiparams  --optimize_out=./ch_PP-OCRv3_det_slim_opt --valid_targets=arm  --optimize_out_type=naive_buffer\n# Convert recognition model\n./opt --model_file=./ch_PP-OCRv3_rec_slim_infer/inference.pdmodel  --param_file=./ch_PP-OCRv3_rec_slim_infer/inference.pdiparams  --optimize_out=./ch_PP-OCRv3_rec_slim_opt --valid_targets=arm  --optimize_out_type=naive_buffer\n# Convert angle classifier model\n./opt --model_file=./ch_ppocr_mobile_v2.0_cls_slim_infer/inference.pdmodel  --param_file=./ch_ppocr_mobile_v2.0_cls_slim_infer/inference.pdiparams  --optimize_out=./ch_ppocr_mobile_v2.0_cls_slim_opt --valid_targets=arm  --optimize_out_type=naive_buffer\n```\n![output image](https://qengineering.eu/github/PaddleOCRoptimizer.png)\u003cbr\u003e\nThe PaddleOCR engine needs the `*.nd` files later on.\n#### PaddleOCR\nThe last action is to download the PaddleOCR software. PaddleOCR is basically a large package of algorithms written in various computer languages, such as C++ and Python. It is not a deep learning framework like PaddlePaddle or PyTorch.\n```\n$ git clone --depth=1 https://github.com/PaddlePaddle/PaddleOCR.git\n```\n![image](https://user-images.githubusercontent.com/44409029/231420269-3ef55dd6-4a2e-4ef0-bab6-6d75d72de767.png)\n\n\n------------\n\n## Installing the app.\nWith all the tools in place, it is time to build the application.\n```\n$ mkdir MyDir\n$ cd MyDir\n$ git clone https://github.com/Qengineering/PaddleOCR-Lite-Document.git\n```\nYour MyDir folder must now look like this:\n```\n.\n├── include                       (copy of PaddleOCR/deploy/lite/)\n│   ├── clipper.h                   \n│   ├── cls_process.h\n│   ├── crnn_process.h\n│   └── db_post_process.h\n├── src                           (copy of PaddleOCR/deploy/lite/)\n│   ├── clipper.cpp\n│   ├── cls_process.cc\n│   ├── crnn_process.cc\n│   ├── db_post_process.cc\n│   └── ocr_db_crnn.cc\n├── models                        (found in Paddle-Lite/build.opt/lite/api)\n│   ├── ch_ppocr_mobile_v2.0_cls_slim_opt.nb\n│   ├── ch_PP-OCRv3_det_slim_opt.nb\n│   ├── ch_PP-OCRv3_rec_slim_opt.nb\n│   ├── config.txt\n│   └── ppocr_keys_v1.txt\n├── PaddleOCR-Lite-Doc.cbp\n└── WillekePass.jpg\n```\nAs you can see, many files are just copies of the original ones found in the Paddle-Lite example.\u003cbr\u003e\nThe models are the ones you just generated with the optimizer.\u003cbr\u003e\nAs said before, your models must match the Paddle-Lite version. Meaning the supplied models here will have only a short lifespan, as Paddle-Lite will evolve further.\u003cbr\u003e\u003cbr\u003e\nLoad the `PaddleOCR-Lite-Doc.cbp` project file in Code::Blocks and build the app.\u003cbr\u003e\nBuilding the application will take a **very** long time,  more than 4 minutes. Don't despair; just be patient.\u003cbr\u003e\n\n------------\n\n## Running the app.\nOnce successfully built you will find the executable `./ocr_db_crnn` in the `bin/Release` folder.\nThe parameter list:\n```\n./ocr_db_crnn Mode Detection model file Orientation classifier model file Recognition model file  Hardware  Precision Threads Batchsize  Test image path Dictionary  \n```\nSome examples. To run the app with the given passport:\n```\n./ocr_db_crnn system ../../models/ch_PP-OCRv3_det_slim_opt.nb  ../../models/ch_PP-OCRv3_rec_slim_opt.nb  ../../models/ch_ppocr_mobile_v2.0_cls_slim_opt.nb  arm8 INT8 4 1  ../../WillekePass.jpg  ../../models/config.txt  ../../models/ppocr_keys_v1.txt  True\n```\nOnly using detection model\n```\n./ocr_db_crnn  det ../../models/ch_PP-OCRv3_det_slim_opt.nb arm8 INT8 4 1 ../../11.jpg  ../../models/config.txt\n```\nOnly using recognition model\n```\n./ocr_db_crnn  rec ../../models/ch_PP-OCRv3_rec_slim_opt.nb arm8 INT8 4 1 ../../word_1.jpg ../../models/ppocr_keys_v1.txt ../../models/config.txt\n```\n\n------------\n\n## CMake.\nInstead of Code::Blocks, you can also use CMake to build the application.\u003cbr\u003e\nPlease follow the next instructions. Assuming your in the 'main' directory.\u003cbr\u003e\n```\n$ mkdir build\n$ cd build\n$ cmake ..\n$ make  -j4\n\nScanning dependencies of target ocr_db_crnn\n[ 16%] Building CXX object CMakeFiles/ocr_db_crnn.dir/src/ocr_db_crnn.cc.o\n[ 33%] Building CXX object CMakeFiles/ocr_db_crnn.dir/src/db_post_process.cc.o\n[ 50%] Linking CXX executable ../ocr_db_crnn\n[100%] Built target ocr_db_crnn\n\n$ cd ..\n$ tree -L 2\n.\n├── build\n│   ├── CMakeCache.txt\n│   ├── CMakeFiles\n│   ├── cmake_install.cmake\n│   └── Makefile\n├── CMakeLists.txt\n├── include\n│   ├── clipper.h\n│   ├── cls_process.h\n│   ├── crnn_process.h\n│   └── db_post_process.h\n├── models\n│   ├── ch_ppocr_mobile_v2.0_cls_slim_opt.nb\n│   ├── ch_PP-OCRv3_det_slim_opt.nb\n│   ├── ch_PP-OCRv3_rec_slim_opt.nb\n│   ├── config.txt\n│   └── ppocr_keys_v1.txt\n├── ocr_db_crnn\n├── PaddleOCR-Lite-Doc.cbp\n├── PaddleOCR-Lite-Doc.depend\n├── PaddleOCR-Lite-Doc.layout\n├── src\n│   ├── clipper.cpp\n│   ├── cls_process.cc\n│   ├── crnn_process.cc\n│   ├── db_post_process.cc\n│   └── ocr_db_crnn.cc\n└── WillekePass.jpg\n```\nRun. Note, you are now in the 'main' directory, not in the 'bin/Release' created by Code::Blocks.\n```\n$ ./ocr_db_crnn system ./models/ch_PP-OCRv3_det_slim_opt.nb  ./models/ch_PP-OCRv3_rec_slim_opt.nb  ./models/ch_ppocr_mobile_v2.0_cls_slim_opt.nb  arm8 INT8 4 1  ./WillekePass.jpg  ./models/config.txt  ./models/ppocr_keys_v1.txt  True\n```\nOnce ocr_db_crnn works, you may remove the build directory, since we don't need it any more.\n```\n$ sudo rm -rf build\n```\n\n------------\n\n## Notes.\n1. `ppocr_keys_v1.txt` is a Chinese dictionary file. If the nb model is used for English recognition or other language recognition, dictionary file should be replaced with a dictionary of the corresponding language. PaddleOCR provides a variety of dictionaries under ppocr/utils/, including:\n```\ndict/french_dict.txt     # french\ndict/german_dict.txt     # german\nic15_dict.txt            # english\ndict/japan_dict.txt      # japan\ndict/korean_dict.txt     # korean\nppocr_keys_v1.txt        # chinese\n```\n\n2.  `config.txt` of the detector and classifier, as shown below:\n```\nmax_side_len  960          #  Limit the maximum image height and width to 960\ndet_db_thresh  0.3         # Used to filter the binarized image of DB prediction, setting 0.-0.3 has no obvious effect on the result\ndet_db_box_thresh  0.5     # DDB post-processing filter box threshold, if there is a missing box detected, it can be reduced as appropriate\ndet_db_unclip_ratio  1.6   # Indicates the compactness of the text box, the smaller the value, the closer the text box to the text\nuse_direction_classify  0  # Whether to use the direction classifier, 0 means not to use, 1 means to use\nrec_image_height  48       # The height of the input image of the recognition model, the PP-OCRv3 model needs to be set to 48, and the PP-OCRv2 model needs to be set to 32\n```\nPlease note the importance of the **rec_image_height** parameter.\u003cbr\u003e \nWhen using the PaddleOCRv2 models, the height must be 32, otherwise the recognition will be very bad.\u003cbr\u003e\nThe same applies for the PaddleOCRv3 models when running with the wrong height.\u003cbr\u003e\nSo, OCRv2 = 32 | OCRv3 = 48\n\n[![paypal](https://qengineering.eu/images/TipJarSmall4.png)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick\u0026hosted_button_id=CPZTM5BB3FCYL) \n\n\n","funding_links":["https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick\u0026hosted_button_id=CPZTM5BB3FCYL"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqengineering%2Fpaddleocr-lite-document","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqengineering%2Fpaddleocr-lite-document","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqengineering%2Fpaddleocr-lite-document/lists"}