序言
最近有個需求,需要在arm板子上部署一個通用的ocr模型,正好度娘家開源的PaddleOCR效果識別得非常不錯,并且提供了mobile版本,因為業務中對精度要求不是特別的高,而且自己去訓練的話效果還大概率沒有人家的好,所以就不從訓練開始折騰了,索性就直接拿來用,PaddleOCR對于部署來說非常的友好,提供了很多方式的部署代碼,因為我是要用到arm邊緣板子上,所以選擇了paddle-lite方式進行部署,而paddle-lite的部署代碼,在PaddleOCR原始碼的deploy/lite檔案夾中,具體檔案如下:

因為代碼人家都直接給出了,所以直接拿來交叉編譯就行,本文的關鍵在與如何交叉編譯,并將編譯得到的可執行檔案放到板子上運行,
paddle-lite官方檔案
相關詳細的教程paddleocr官方也給出來了,可以直接看PaddleOCR端側部署,但是我感覺他們教程寫的太亂了,參考了大部分他們的教程,還時用自己的方式進行編譯,具體程序看正文,
一、環境搭建
1.1 運行準備
- ubuntu電腦一臺(提供交叉編譯環境)
- arm板子一塊(rk3328,armv8,可執行檔案運行環境)
1.2 準備交叉編譯環境
我這里的交叉編譯環境是使用的rk3328自帶的armv8交叉編譯工具鏈,在其完整的sdk中提供,不需要對其進行任何修改,記住這個路徑即可,在編譯的時候需要指定:

如果是其他的板子,可以看其是否sdk中有提供,如果沒有提供的話,可以根據自己的系統按照paddleocr官方教程進行準備:

1.3 準備paddle-lite預測庫
根據官方的教程,paddle-lite庫檔案準備有兩種方式:
-
直接下載
paddle-lite提供了已經編譯好的庫檔案,只需要根據自己的系統進行下載即可,比如我這里要使用的是在armv8系統上,所以我可以直接到這里中下載paddle-lite v2.9預測庫檔案:

為什么是下載這個呢?注意看幾個對應的標簽:armv8、with_extra、with_cv,在原始碼編譯的時候會提到, -
原始碼編譯
Paddle-Lite的編譯方式如下:
git clone https://github.com/PaddlePaddle/Paddle-Lite.git
cd Paddle-Lite
# 切換到Paddle-Lite release/v2.9 穩定分支
git checkout release/v2.9
./lite/tools/build_android.sh --arch=armv8 --with_cv=ON --with_extra=ON
在編譯中,放開了–with_cv=ON --with_extra=ON 選項,并指定了–arch=armv8,所以正好和上面下載的相對應,
兩種預測庫的獲取方式,如果嫌麻煩的話可以選第一種,不嫌麻煩就選第二種,我這里是直接選第一種,直接下載下來然后解壓得到如下兩個檔案夾:

其中cxx中是paddle-lite的預測庫頭檔案和動態庫檔案,這個檔案夾我們可以直接拷貝到自己的專案中呼叫;demo中是提供了示例代碼,供使用者呼叫參考,
二、代碼整合
好了,我們現在已經有paddleOCR的部署代碼,也有paddle-lite的預測庫檔案了,那怎么將他們整合到一起編譯呢?首先新建一個檔案夾,取名paddle_lite_ocr,將第一部分中的paddle-lite的部署代碼拷貝進去,因為我是按照自己的方式去編譯的,所以只需要拷貝這幾個原始碼即可:

然后將剛才的預測庫中cxx的檔案拷貝到該目錄下,新建一個model檔案夾,用于存放模型檔案,模型檔案可以官方教程中下載,如果不想自己手動優化的話:

下載下來的模型檔案放到model檔案夾中,
等等,是不是忘了一件事情,opencv庫呢?預測的時候還需要opencv庫的支持,所以我們還需要對opencv源檔案進行交叉編譯,具體程序參考這個鏈接ubuntu16.04交叉編譯opencv 移植到rk1808上,將編譯得到的opencv檔案也打包存放到cxx檔案中供呼叫:

最后的檔案目錄結構如下,下面的源檔案沒有截全,反正就是上面拷貝的:

除了拷貝過來的源代碼,你可能還需要clipper.h 和clipper.cpp這兩個檔案,因為代碼里有呼叫,但是又找不到這兩個檔案,太長了我不想貼出來,太占篇幅,我告訴你們去哪里找,在chineseocr_lite中拷貝過來


接著需要新建一個CMakeLists.txt檔案,檔案內容如下:
cmake_minimum_required(VERSION 2.8)
project(paddle_lite_ocr)
set(TARGET paddle_lite_ocr)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
# Set ARMLINUX_ARCH_ABI to armv8 or armv7 or armv7hf
set(ARMLINUX_ARCH_ABI armv8)
# 1. path to Paddle-Lite lib
set(LITE_DIR "${CMAKE_SOURCE_DIR}/cxx")
# 2. link Paddle-Lite directory
link_directories(${LITE_DIR}/lib)
include_directories(${LITE_DIR}/include)
FIND_PACKAGE( OpenMP REQUIRED)
if(OPENMP_FOUND)
message("OPENMP FOUND")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
endif()
# opencv
set(OpenCV_DIR ${LITE_DIR}/opencv-linux-aarch64/share/OpenCV)
find_package(OpenCV REQUIRED)
set(CMAKE_CXX_STANDARD 14)
# 3.add executable output
add_executable(${TARGET} ocr_db_crnn.cc cls_process.cc db_post_process.cc crnn_process.cc clipper.cpp)
target_link_libraries(${TARGET} -lpaddle_light_api_shared ${OpenCV_LIBS})
target_link_libraries(${TARGET} -ldl)
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/install/paddle_lite_ocr)
install(TARGETS paddle_lite_ocr DESTINATION ./)
#install(DIRECTORY model DESTINATION ./)
呼叫相關鏈接庫,然后再新建一個build.sh檔案,用于指定工具鏈編譯,內容如下:
#!/bin/bash
set -e
# for rk3328 aarch64
GCC_COMPILER=/home/cai/rk3328_linux/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu
ROOT_PWD=$( cd "$( dirname $0 )" && cd -P "$( dirname "$SOURCE" )" && pwd )
# build rockx
BUILD_DIR=${ROOT_PWD}/build
if [[ ! -d "${BUILD_DIR}" ]]; then
mkdir -p ${BUILD_DIR}
fi
cd ${BUILD_DIR}
cmake .. \
-DCMAKE_C_COMPILER=${GCC_COMPILER}-gcc \
-DCMAKE_CXX_COMPILER=${GCC_COMPILER}-g++
make -j4
make install
cd -
編譯的時候只需要指定GCC_COMPILER交叉編譯工具鏈路徑即可,然后直接在目錄下運行./build.sh

編譯成功后的可執行檔案在install/paddle_lite_ocr檔案夾中:

將該檔案通過scp -r或者adb,push到板子上執行即可,
三、ARM板子上的環境準備
不過在push到板子上時運行需要一些依賴庫的支持,因為板子上是沒有opencv和paddle-lite的環境依賴的,所以需要把剛才交叉編譯過的opencv的so檔案拷貝到板子上的/usr/lib目錄中,so檔案在如下目錄:

全部拷貝到/usr/lib,然后還有這個也一起拷貝過去:

當然別忘了把模型檔案,字典檔案,config.txt檔案一起拷貝過去,最終運行的目錄檔案如下:

這時候只需要運行如下命令:
./paddle_lite_ocr ch_ppocr_mobile_v2.0_det_slim_opt.nb ch_ppocr_mobile_v2.0_rec_slim_opt.nb ch_ppocr_mobile_v2.0_cls_slim_opt.nb model/test_img/7.png ppocr_keys_v1.txt
傳入五個引數,分別是:文字檢測模型路徑、文字識別模型路徑、文字方向模型路徑、測驗圖片路徑、字典路徑,找兩張圖片來測驗一下:

運行結果:


運行結果:

推理是在cpu上進行的,rk3328只有四核A53的cpu,算力比較差,所以推理時間長了一些;還有一些閾值沒有調好,識別效果可能會差了一點,如果有需要的話可以再對閾值進行調整,應該會更好,
我也用了ncnn進行部署,作為對比,paddle-lite要比ncnn效果差很多,具體的對比有時間我再寫一篇ncnn部署的文章,好了,就先這樣吧,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/345587.html
標籤:其他
