Commit 3b86a3cf authored by benjaminwan's avatar benjaminwan
Browse files

version: 1.1.0

parent 22437c6f
name: Builder
on:
workflow_dispatch:
push:
tags:
- '*'
jobs:
ubuntu1804:
runs-on: ubuntu-18.04
env:
ONNX_VERSION: 1.12.1
ONNX_PKG_NAME: onnxruntime-1.12.1-ubuntu1804-static
CV_VERSION: 4.6.0
CV_PKG_NAME: opencv-4.6.0-ubuntu1804
steps:
# 检出代码
- uses: actions/checkout@v3
# 下载onnxruntime-static
- name: download onnxruntime-static
run: |
cd onnxruntime-static
wget https://github.com/RapidAI/OnnxruntimeBuilder/releases/download/${{ env.ONNX_VERSION }}/${{ env.ONNX_PKG_NAME }}.7z -O ${{ env.ONNX_PKG_NAME }}.7z
7z x ${{ env.ONNX_PKG_NAME }}.7z -aoa
# 下载opencv-static
- name: download opencv-static
run: |
cd opencv-static
wget https://github.com/RapidAI/OpenCVBuilder/releases/download/${{ env.CV_VERSION }}/${{ env.CV_PKG_NAME }}.7z -O ${{ env.CV_PKG_NAME }}.7z
7z x ${{ env.CV_PKG_NAME }}.7z -aoa
# 编译
- name: build
run: |
chmod a+x build-default.sh &&./build-default.sh
# 使用7z压缩
- name: 7zip
run: |
mkdir linux-bin
cp run-benchmark.sh linux-bin/run-benchmark.sh
cp run-test.sh linux-bin/run-test.sh
cp -r images linux-bin/images
mv Linux-BIN/install/bin linux-bin/Linux-BIN
7z a linux-bin.7z linux-bin
mkdir linux-jni
mv Linux-JNI/install linux-jni/Linux-JNI
7z a linux-jni.7z linux-jni
mkdir linux-clib
mv Linux-CLIB/install linux-clib/Linux-CLIB
7z a linux-clib.7z linux-clib
# 上传artifact
- name: upload
uses: actions/upload-artifact@v3
with:
name: linux-bin
path: linux-bin.7z
- name: upload
uses: actions/upload-artifact@v3
with:
name: linux-jni
path: linux-jni.7z
- name: upload
uses: actions/upload-artifact@v3
with:
name: linux-clib
path: linux-clib.7z
macos1015:
runs-on: macos-latest
env:
ONNX_VERSION: 1.12.1
ONNX_PKG_NAME: onnxruntime-1.12.1-macos1015-static
CV_VERSION: 4.6.0
CV_PKG_NAME: opencv-4.6.0-macos1015
steps:
# 检出代码
- uses: actions/checkout@v3
# 安装openmp
- name: install openmp
run: |
brew install libomp
# 下载onnxruntime-static
- name: download onnxruntime-static
run: |
cd onnxruntime-static
wget https://github.com/RapidAI/OnnxruntimeBuilder/releases/download/${{ env.ONNX_VERSION }}/${{ env.ONNX_PKG_NAME }}.7z -O ${{ env.ONNX_PKG_NAME }}.7z
7z x ${{ env.ONNX_PKG_NAME }}.7z -aoa
# 下载opencv-static
- name: download opencv-static
run: |
cd opencv-static
wget https://github.com/RapidAI/OpenCVBuilder/releases/download/${{ env.CV_VERSION }}/${{ env.CV_PKG_NAME }}.7z -O ${{ env.CV_PKG_NAME }}.7z
7z x ${{ env.CV_PKG_NAME }}.7z -aoa
# 编译
- name: build
run: |
chmod a+x build-default.sh &&./build-default.sh
# 使用7z压缩
- name: 7zip
run: |
mkdir macos-bin
cp run-benchmark.sh macos-bin/run-benchmark.sh
cp run-test.sh macos-bin/run-test.sh
cp -r images macos-bin/images
mv Darwin-BIN/install/bin macos-bin/Darwin-BIN
7z a macos-bin.7z macos-bin
mkdir macos-jni
mv Darwin-JNI/install macos-jni/Darwin-JNI
7z a macos-jni.7z macos-jni
mkdir macos-clib
mv Darwin-CLIB/install macos-clib/Darwin-CLIB
7z a macos-clib.7z macos-clib
# 上传artifact
- name: upload
uses: actions/upload-artifact@v3
with:
name: macos-bin
path: macos-bin.7z
- name: upload
uses: actions/upload-artifact@v3
with:
name: macos-jni
path: macos-jni.7z
- name: upload
uses: actions/upload-artifact@v3
with:
name: macos-clib
path: macos-clib.7z
windows-vs2019:
runs-on: windows-2019
env:
ONNX_VERSION: 1.12.1
ONNX_PKG_NAME: onnxruntime-1.12.1-vs2019-static-mt
CV_VERSION: 4.6.0
CV_PKG_NAME: opencv-4.6.0-windows-vs2019-mt
steps:
# 检出代码
- uses: actions/checkout@v3
# 下载onnxruntime-static
- name: download onnxruntime-static
run: |
cd onnxruntime-static
Invoke-WebRequest -Uri https://github.com/RapidAI/OnnxruntimeBuilder/releases/download/${{ env.ONNX_VERSION }}/${{ env.ONNX_PKG_NAME }}.7z -OutFile ${{ env.ONNX_PKG_NAME }}.7z
7z x ${{ env.ONNX_PKG_NAME }}.7z -aoa
# 下载opencv-static
- name: download opencv-static
run: |
cd opencv-static
Invoke-WebRequest -Uri https://github.com/RapidAI/OpenCVBuilder/releases/download/${{ env.CV_VERSION }}/${{ env.CV_PKG_NAME }}.7z -OutFile ${{ env.CV_PKG_NAME }}.7z
7z x ${{ env.CV_PKG_NAME }}.7z -aoa
# 编译
- name: build
run: |
./build-default.bat
# 使用7z压缩
- name: 7zip
run: |
mkdir windows-bin
cp run-benchmark.bat windows-bin/run-benchmark.bat
cp run-test.bat windows-bin/run-test.bat
cp -r images windows-bin/images
mv win-BIN-x64/install/bin windows-bin/win-BIN-x64
mv win-BIN-Win32/install/bin windows-bin/win-BIN-Win32
7z a windows-bin.7z windows-bin
mkdir windows-jni
mv win-JNI-x64/install windows-jni/win-JNI-x64
mv win-JNI-Win32/install windows-jni/win-JNI-Win32
7z a windows-jni.7z windows-jni
mkdir windows-clib
mv win-CLIB-x64/install windows-clib/win-CLIB-x64
mv win-CLIB-Win32/install windows-clib/win-CLIB-Win32
7z a windows-clib.7z windows-clib
# 上传artifact
- name: upload
uses: actions/upload-artifact@v3
with:
name: windows-bin
path: windows-bin.7z
- name: upload
uses: actions/upload-artifact@v3
with:
name: windows-jni
path: windows-jni.7z
- name: upload
uses: actions/upload-artifact@v3
with:
name: windows-clib
path: windows-clib.7z
release:
needs: [ ubuntu1804, macos1015, windows-vs2019 ]
runs-on: ubuntu-latest
steps:
# 检出代码
- uses: actions/checkout@v3
# 获取所有的git log和tag
- name: Unshallow
run: git fetch --prune --unshallow
# 获取git log 从 previousTag 到 lastTag
- name: Get git log
id: git-log
run: |
previousTag=$(git describe --abbrev=0 --tags `git rev-list --tags --skip=1 --max-count=1`)
lastTag=$(git describe --abbrev=0 --tags)
echo "previousTag:$previousTag ~ lastTag:$lastTag"
log=$(git log $previousTag..$lastTag --pretty=format:'- %cd %an: %s\n' --date=format:'%Y-%m-%d %H:%M:%S')
echo "$log"
echo "log_state="$log"" >> $GITHUB_ENV
# 创建Changelog文件 triggered by git tag push
- name: Generate Changelog
if: startsWith(github.ref, 'refs/tags/')
run: |
echo -e '${{ env.log_state }}' > Release.txt
# Cat Changelog triggered by git tag push
- name: Cat Changelog
if: startsWith(github.ref, 'refs/tags/')
run: |
cat Release.txt
# 下载artifact
- name: download
uses: actions/download-artifact@v3
with:
path: artifacts
# 查看artifact
- name: list artifact
run: |
tree artifacts
# 创建release
- name: create-release
id: create-release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ${{ github.ref }}
body_path: Release.txt
draft: false
prerelease: false
- name: upload-linux-bin
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PKG_NAME: linux-bin
with:
upload_url: ${{ steps.create-release.outputs.upload_url }}
asset_path: artifacts/${{ env.PKG_NAME }}/${{ env.PKG_NAME }}.7z
asset_name: ${{ env.PKG_NAME }}.7z
asset_content_type: application/x-7z-compressed
- name: upload-linux-jni
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PKG_NAME: linux-jni
with:
upload_url: ${{ steps.create-release.outputs.upload_url }}
asset_path: artifacts/${{ env.PKG_NAME }}/${{ env.PKG_NAME }}.7z
asset_name: ${{ env.PKG_NAME }}.7z
asset_content_type: application/x-7z-compressed
- name: upload-linux-clib
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PKG_NAME: linux-clib
with:
upload_url: ${{ steps.create-release.outputs.upload_url }}
asset_path: artifacts/${{ env.PKG_NAME }}/${{ env.PKG_NAME }}.7z
asset_name: ${{ env.PKG_NAME }}.7z
asset_content_type: application/x-7z-compressed
- name: upload-macos-bin
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PKG_NAME: macos-bin
with:
upload_url: ${{ steps.create-release.outputs.upload_url }}
asset_path: artifacts/${{ env.PKG_NAME }}/${{ env.PKG_NAME }}.7z
asset_name: ${{ env.PKG_NAME }}.7z
asset_content_type: application/x-7z-compressed
- name: upload-macos-jni
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PKG_NAME: macos-jni
with:
upload_url: ${{ steps.create-release.outputs.upload_url }}
asset_path: artifacts/${{ env.PKG_NAME }}/${{ env.PKG_NAME }}.7z
asset_name: ${{ env.PKG_NAME }}.7z
asset_content_type: application/x-7z-compressed
- name: upload-macos-clib
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PKG_NAME: macos-clib
with:
upload_url: ${{ steps.create-release.outputs.upload_url }}
asset_path: artifacts/${{ env.PKG_NAME }}/${{ env.PKG_NAME }}.7z
asset_name: ${{ env.PKG_NAME }}.7z
asset_content_type: application/x-7z-compressed
- name: upload-windows-bin
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PKG_NAME: windows-bin
with:
upload_url: ${{ steps.create-release.outputs.upload_url }}
asset_path: artifacts/${{ env.PKG_NAME }}/${{ env.PKG_NAME }}.7z
asset_name: ${{ env.PKG_NAME }}.7z
asset_content_type: application/x-7z-compressed
- name: upload-windows-jni
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PKG_NAME: windows-jni
with:
upload_url: ${{ steps.create-release.outputs.upload_url }}
asset_path: artifacts/${{ env.PKG_NAME }}/${{ env.PKG_NAME }}.7z
asset_name: ${{ env.PKG_NAME }}.7z
asset_content_type: application/x-7z-compressed
- name: upload-windows-clib
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PKG_NAME: windows-clib
with:
upload_url: ${{ steps.create-release.outputs.upload_url }}
asset_path: artifacts/${{ env.PKG_NAME }}/${{ env.PKG_NAME }}.7z
asset_name: ${{ env.PKG_NAME }}.7z
asset_content_type: application/x-7z-compressed
# 获取指定时区的时间
# https://github.com/marketplace/actions/get-time-action
- name: Get Time
id: time
uses: JantHsueh/get-time-action@master
with:
timeZone: 8
# 向钉钉发送消息
# https://github.com/marketplace/actions/web-request-action
- name: dingtalk
uses: satak/webrequest-action@master
with:
url: ${{ secrets.DINGTALK_WEBHOOK }}
method: POST
payload: '{"msgtype": "text", "text": {"content": "版本更新: ${{ github.repository }}-版本号: ${{ github.ref }} \n 编译时间: ${{ steps.time.outputs.time }} \n 距上个正式版的更新记录: \n${{ env.log_state }}"}}'
headers: '{"Content-Type": "application/json"}'
\ No newline at end of file
# Created by .ignore support plugin (hsz.mobi)
### Python template
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
#idea
.idea
cmake-build-debug/
build/
build-lib/
/models/*.onnx
onnxruntime-shared/
onnxruntime-static/*
!/onnxruntime-static/OnnxRuntimeWrapper.cmake
opencv-static/*
!/opencv-static/OpenCVWrapperConfig.cmake
opencv-shared/
/images/*-result.*
\ No newline at end of file
# 编译说明
### 依赖的第三方库下载
1. 下载opencv,[下载地址](https://github.com/RapidAI/OpenCVBuilder/releases)
* OpenCV静态库:opencv-(版本号)-平台.7z,
* 把压缩包解压到项目根目录,windows平台需要注意目录层次,解压后目录结构如下
* windows平台分为mt和md版,mt代表静态链接CRT,md代表动态链接CRT
```
OcrLiteNcnn/opencv-static
├── OpenCVWrapperConfig.cmake
├── linux
├── macos
├── windows-x64
└── windows-x86
```
2. 下载onnxruntime,[下载地址](https://github.com/RapidAI/OnnxruntimeBuilder/releases)
* static为静态库:onnxruntime-(版本号)-平台-static.7z
* shared为动态库:onnxruntime-(版本号)-平台-shared.7z
* 一般情况下使用静态库即可
* 把压缩包解压到项目根目录,windows平台需要注意目录层次,解压后目录结构如下
* windows平台分为mt和md版,mt代表静态链接CRT,md代表动态链接CRT
```
OcrLiteNcnn/onnxruntime-static
├── OnnxRuntimeWrapper.cmake
├── linux
├── macos
├── windows-x64
└── windows-x86
```
### 编译环境
1. Windows 10 x64
2. macOS 10.15
3. Linux Ubuntu 1804 x64
**注意:以下说明仅适用于本机编译。如果需要交叉编译为arm等其它平台(参考android),则需要先交叉编译所有第三方依赖库(ncnn、opencv),然后再把依赖库整合替换到本项目里。**
### Windows编译说明
#### 注意:从OnnxRuntime 1.7.0 ,只支持vs2019编译环境
#### Windows nmake编译
1. 安装VS2019,安装时,至少选中'使用C++的桌面开发'
2. cmake>=3.12请自行下载&配置,[下载地址](https://cmake.org/download/)
3. 开始菜单打开"x64 Native Tools Command Prompt for VS 2019"或"适用于 VS2017 的 x64 本机工具",并转到本项目根目录
4. 运行```build.bat```并按照提示输入选项,最后选择'编译成可执行文件'
5. 编译完成后运行```run-test.bat```进行测试(注意修改脚本内的目标图片路径)
6. 编译JNI动态运行库(可选,可用于java调用)
* 下载jdk-8u221-windows-x64.exe,安装选项默认(确保“源代码”项选中),安装完成后,打开“系统”属性->高级->环境变量
* 新建“系统变量”,变量名```JAVA_HOME``` ,变量值```C:\Program Files\Java\jdk1.8.0_221``
* 新建“系统变量”,变量名```CLASSPATH``` ,变量值```.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;``
* 编辑“系统变量”Path,Win7在变量值头部添加```%JAVA_HOME%\bin;``` ,win10直接添加一行```%JAVA_HOME%\bin```
* 开始菜单打开"x64 Native Tools Command Prompt for VS 2019"或"适用于 VS2017 的 x64 本机工具",并转到本项目根目录
* 运行```build.bat```并按照提示输入选项,最后选择'编译成JNI动态库'
#### Windows Visual Studio编译说明
1. VS2019,cmake……等安装配置参考上述步骤。
2. 运行generate-vs-project.bat,输入数字选择要生成的visual studio项目解决方案版本。
3. 根据你的编译环境,进入build-xxxx-x86或x64文件夹,打开OcrLiteNcnn.sln。
4. 在顶部工具栏选择Release,在右边的"解决方案"窗口,右键选中"ALL_BUILD"->生成。要选择Debug,则您必须自行编译Debug版的opencv或ncnn。
#### Windows部署说明
1. 编译选项选择第三方库为动态库时,部署的时候记得把dll复制到可执行文件目录。
2. 部署时如果提示缺少"VCRUNTIME140_1.dll",下载安装适用于 Visual Studio 2015、2017 和 2019 的 Microsoft Visual C++ 可再发行软件包,
[下载地址](https://support.microsoft.com/zh-cn/help/2977003/the-latest-supported-visual-c-downloads)
### Mac编译说明
1. macOS Catalina 10.15.x,安装Xcode 12.1,并安装Xcode Command Line Tools, 终端运行```xcode-select –install```
2. 自行下载安装HomeBrew,cmake >=3.17[下载地址](https://cmake.org/download/)
3. libomp: ```brew install libomp```
4. 终端打开项目根目录,```./build.sh```并按照提示输入选项,最后选择'编译成可执行文件'
5. 测试:```./run-test.sh```(注意修改脚本内的目标图片路径)
6. 编译JNI动态运行库(可选,可用于java调用)
* 下载jdk-8u221-macosx-x64.dmg,安装。
* 编辑用户目录下的隐藏文件```.zshrc``` ,添加```export JAVA_HOME=$(/usr/libexec/java_home)```
* 运行```build.sh```并按照提示输入选项,最后选择'编译成JNI动态库'
#### macOS部署说明
opencv或onnxruntime使用动态库时,参考下列方法:
* 把动态库所在路径加入DYLD_LIBRARY_PATH搜索路径
* 把动态库复制或链接到到/usr/lib
### Linux编译说明
1. Ubuntu18.04 LTS 其它发行版(请自行编译依赖库opencv和ncnn,或自行适配官方发布的动态库)
2. ```sudo apt-get install build-essential```
3. g++>=5,cmake>=3.17[下载地址](https://cmake.org/download/)
4. 终端打开项目根目录,```./build.sh```并按照提示输入选项,最后选择'编译成可执行文件'
5. 测试:```./run-test.sh```(注意修改脚本内的目标图片路径)
6. 编译JNI动态运行库(可选,可用于java调用)
* 下载jdk-8u221并安装配置
* 运行```build.sh```并按照提示输入选项,最后选择'编译成JNI动态库'
* **注意:编译JNI时,g++版本要求>=6**
#### Linux部署说明
opencv或onnxruntime使用动态库时,参考下列方法:
* 把动态库所在路径加入LD_LIBRARY_PATH搜索路径
* 把动态库复制或链接到到/usr/lib
### 编译参数说明
build.sh编译参数
1. ```OCR_OUTPUT="BIN"或"JNI"或"CLIB"```: BIN时编译为可执行文件,JNI时编译为java jni 动态库,CLIB时编译为 C动态库;
if (WIN32)
cmake_minimum_required(VERSION 3.12)
elseif (APPLE)
cmake_minimum_required(VERSION 3.17)
elseif (UNIX)
cmake_minimum_required(VERSION 3.17)
endif ()
project(RapidOcrOnnx)
# Output BIN JNI CLIB
if (NOT DEFINED OCR_OUTPUT)
set(OCR_OUTPUT "BIN")
message(STATUS "No OCR_OUTPUT, defaulting to BIN")
endif ()
option(OCR_BENCHMARK "build benchmark" ON)
set(OCR_BENCHMARK ON)
#set(OCR_OUTPUT "BIN")
set(CMAKE_CXX_STANDARD 11)
add_definitions(-DUNICODE -D_UNICODE)
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
add_definitions("-Wall -g -O0")
else ()
add_definitions("-Wall")
endif ()
# OnnxRuntime
include(${CMAKE_CURRENT_SOURCE_DIR}/onnxruntime-static/OnnxRuntimeWrapper.cmake)
find_package(OnnxRuntime REQUIRED)
if (OnnxRuntime_FOUND)
message(STATUS "OnnxRuntime_LIBS: ${OnnxRuntime_LIBS}")
message(STATUS "OnnxRuntime_INCLUDE_DIRS: ${OnnxRuntime_INCLUDE_DIRS}")
else ()
message(FATAL_ERROR "onnxruntime Not Found!")
endif (OnnxRuntime_FOUND)
# OpenCV
set(BUILD_SHARED_LIBS false)
include(${CMAKE_CURRENT_SOURCE_DIR}/opencv-static/OpenCVWrapperConfig.cmake)
find_package(OpenCV REQUIRED)
if (OpenCV_FOUND)
message(STATUS "OpenCV_LIBS: ${OpenCV_LIBS}")
message(STATUS "OpenCV_INCLUDE_DIRS: ${OpenCV_INCLUDE_DIRS}")
else ()
message(FATAL_ERROR "opencv Not Found!")
endif (OpenCV_FOUND)
# project include
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
# source
file(GLOB OCR_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
set(OCR_COMPILE_CODE ${OCR_SRC})
# JNI
if (OCR_OUTPUT STREQUAL "JNI")
find_package(JNI REQUIRED)
if (JNI_FOUND)
message("JNI FOUND")
message(STATUS "JNI_LIBS: ${JNI_LIBS}")
message(STATUS "JNI_INCLUDE_DIRS: ${JNI_INCLUDE_DIRS}")
include_directories(${JNI_INCLUDE_DIRS})
else ()
message(FATAL_ERROR "JNI Not Found!")
endif ()
endif ()
if (OCR_OUTPUT STREQUAL "JNI") # JNI
add_library(RapidOcrOnnx SHARED ${OCR_COMPILE_CODE})
target_compile_definitions(RapidOcrOnnx PRIVATE __JNI__)
target_link_libraries(RapidOcrOnnx ${OnnxRuntime_LIBS} ${OpenCV_LIBS} ${JNI_LIBS})
elseif (OCR_OUTPUT STREQUAL "CLIB") # CLIB
add_library(RapidOcrOnnx SHARED ${OCR_COMPILE_CODE})
target_compile_definitions(RapidOcrOnnx PRIVATE __CLIB__)
target_link_libraries(RapidOcrOnnx ${OnnxRuntime_LIBS} ${OpenCV_LIBS})
elseif (OCR_OUTPUT STREQUAL "BIN") # BIN
add_executable(RapidOcrOnnx ${OCR_COMPILE_CODE})
target_compile_definitions(RapidOcrOnnx PRIVATE __EXEC__)
target_link_libraries(RapidOcrOnnx ${OnnxRuntime_LIBS} ${OpenCV_LIBS})
endif ()
install(TARGETS RapidOcrOnnx EXPORT RapidOcrOnnx)
if (OCR_OUTPUT STREQUAL "CLIB") # CLIB
file(GLOB OCR_INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h)
install(FILES ${OCR_INCLUDE} DESTINATION include)
endif ()
# benchmark
if (OCR_BENCHMARK AND (OCR_OUTPUT STREQUAL "BIN"))
add_executable(benchmark benchmark/benchmark.cpp
src/AngleNet.cpp
src/clipper.cpp
src/CrnnNet.cpp
src/DbNet.cpp
src/getopt.cpp
src/OcrLite.cpp
src/OcrUtils.cpp)
target_link_libraries(benchmark ${OnnxRuntime_LIBS} ${OpenCV_LIBS})
target_compile_definitions(benchmark PRIVATE __EXEC__)
install(TARGETS benchmark EXPORT benchmark
ARCHIVE DESTINATION staticlib
LIBRARY DESTINATION sharedlib
RUNTIME DESTINATION bin)
endif ()
# Windows Link CRT
if (OCR_BUILD_CRT STREQUAL "True")
include(${CMAKE_CURRENT_SOURCE_DIR}/OcrCRTLinkage.cmake)
endif ()
\ No newline at end of file
if (WIN32)
foreach(flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endif()
if(${flag_var} MATCHES "/MDd")
string(REGEX REPLACE "/MDd" "/MTd" ${flag_var} "${${flag_var}}")
endif()
endforeach(flag_var)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB:atlthunk.lib")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcpmt.lib /NODEFAULTLIB:msvcrt.lib")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:libcpmtd.lib /NODEFAULTLIB:msvcrtd.lib")
message(STATUS "OCR_BUILD_CRT True")
endif ()
# RapidOcrOnnx
### 联系方式
* QQ①群:887298230
### Project下载
* 整合好源码和依赖库的完整工程项目,可以在Release中下载(github)
* 可到Q群共享内下载,以Project开头的压缩包文件为源码工程,例:Project_RapidOcrOnnx-版本号.7z
* 如果想自己折腾,则请继续阅读本说明
### Demo下载(win、mac、linux)
* 编译好的demo,可以在release中下载,或者Q群共享内下载
* 各平台可执行文件:linux-bin.7z、macos-bin.7z、windows-bin.7z
* 用于java的jni库:linux-jni.7z、macos-jni.7z、windows-jni.7z
* 用于C的动态库:linux-clib.7z、macos-clib.7z、windows-clib.7z
* 注意:linux编译平台为ubuntu18.04,如果你的linux版本无法运行demo,请自行从源码编译依赖库和完整项目。
### 介绍
请查看项目主仓库:https://github.com/RapidAI/RapidOCR
这个项目使用onnxruntime框架进行推理
采用onnxruntime框架[https://github.com/microsoft/onnxruntime](https://github.com/microsoft/onnxruntime)
### 更新说明
#### 2021-10-15 update
* opencv 4.6.0
* onnxruntime 1.12.1
* windows支持mt版引用库
### 模型下载
整合好的范例工程自带了模型,在models文件夹中
```
RapidOcrOnnx/models
├── ch_PP-OCRv3_det_infer.onnx
├── ch_PP-OCRv3_rec_infer.onnx
├── ch_ppocr_mobile_v2.0_cls_infer.onnx
└── ppocr_keys_v1.txt
```
### [编译说明](./BUILD.md)
### 测试说明
1. 根据系统下载对应的程序包linux-bin.7z、macos-bin.7z、windows-bin.7z,并解压.
2. 把上面的模型下载,解压到第一步解压的文件夹里.
3. 终端运行run-test.sh或命令行运行run-test.bat,查看识别结果.
4. 终端运行run-benchmark.sh或命令行运行run-benchmark.bat,查看识别过程平均耗时.
### FAQ
#### windows静态链接msvc
- 作用:静态链接CRT(mt)可以让编译出来的包,部署时不需要安装c++运行时,但会增大包体积;
- 需要mt版的引用库,参考编译说明,下载mt版的库;
#### windows提示缺少"VCRUNTIME140_1.dll"
下载安装适用于 Visual Studio 2015、2017 和 2019 的 Microsoft Visual C++ 可再发行软件包
[下载地址](https://support.microsoft.com/zh-cn/help/2977003/the-latest-supported-visual-c-downloads)
#### Windows7执行错误|中文乱码
1. cmd窗口左上角-属性
2. 字体选项卡-选择除了“点阵字体”以外的TrueType字体,例如:Lucida Console、宋体
3. 重新执行bat
### 输入参数说明
* 请参考main.h中的命令行参数说明。
* 每个参数有一个短参数名和一个长参数名,用短的或长的均可。
1. ```-d或--models```:模型所在文件夹路径,可以相对路径也可以绝对路径。
2. ```-1或--det```:det模型文件名(含扩展名)
3. ```-2或--cls```:cls模型文件名(含扩展名)
4. ```-3或--rec```:rec模型文件名(含扩展名)
5. ```-4或--keys```:keys.txt文件名(含扩展名)
6. ```-i或--image```:目标图片路径,可以相对路径也可以绝对路径。
7. ```-t或--numThread```:线程数量。
8. ```-p或--padding```:图像预处理,在图片外周添加白边,用于提升识别率,文字框没有正确框住所有文字时,增加此值。
9. ```-s或--maxSideLen```
:按图片最长边的长度,此值为0代表不缩放,例:1024,如果图片长边大于1024则把图像整体缩小到1024再进行图像分割计算,如果图片长边小于1024则不缩放,如果图片长边小于32,则缩放到32。
10. ```-b或--boxScoreThresh```:文字框置信度门限,文字框没有正确框住所有文字时,减小此值。
11. ```-o或--boxThresh```:请自行试验。
12. ```-u或--unClipRatio```:单个文字框大小倍率,越大时单个文字框越大。此项与图片的大小相关,越大的图片此值应该越大。
13. ```-a或--doAngle```:启用(1)/禁用(0) 文字方向检测,只有图片倒置的情况下(旋转90~270度的图片),才需要启用文字方向检测。
14. ```-A或--mostAngle```:启用(1)/禁用(0) 角度投票(整张图片以最大可能文字方向来识别),当禁用文字方向检测时,此项也不起作用。
15. ```-h或--help```:打印命令行帮助。
### 关于内存泄漏与valgrind
* 项目根目录的valgrind-memcheck.sh用来检查内存泄漏(需要debug编译)。
* 常见的并行库有tbb,hpx,openmp,gcd,concurrency,pthread
* 并行库的种类可以看:https://docs.opencv.org/4.x/db/d05/tutorial_config_reference.html
* 测试了openmp和pthread,目前已知这类并行库会导致检查报告中出现"possibly lost"
* opencv只做简单的图像预处理,可以完全不使用任何并行库,但需要定制编译
* onnxruntime1.6.0或之前,默认引用openmp,从1.7.0开始默认关闭openmp并使用自带的ThreadPool代码
* 阅读报告可以看出"possibly lost"发生位置均在引用的第三方库(如果使用了并行库的话),如opencv或onnxruntime
* "possibly lost"不一定是内存泄露
* 如果opencv想定制编译不使用任何并行库,可以使用以下参数进行编译
```
-DWITH_TBB=OFF
-DWITH_HPX=OFF
-DWITH_OPENMP=OFF
-DWITH_GCD=OFF
-DWITH_CONCURRENCY=OFF
-DWITH_PTHREADS_PF=OFF
```
\ No newline at end of file
#include <cstdio>
#include "main.h"
#include "version.h"
#include "OcrLite.h"
#include "OcrUtils.h"
void printHelp(FILE *out, char *argv0) {
fprintf(out, " ------- Usage -------\n");
fprintf(out, "%s %s", argv0, usageMsg);
fprintf(out, " ------- Required Parameters -------\n");
fprintf(out, "%s", requiredMsg);
fprintf(out, " ------- Optional Parameters -------\n");
fprintf(out, "%s", optionalMsg);
fprintf(out, " ------- Other Parameters -------\n");
fprintf(out, "%s", otherMsg);
fprintf(out, " ------- Examples -------\n");
fprintf(out, example1Msg, argv0);
fprintf(out, example2Msg, argv0);
}
int main(int argc, char **argv) {
if (argc <= 1) {
printHelp(stderr, argv[0]);
return -1;
}
std::string modelsDir, modelDetPath, modelClsPath, modelRecPath, keysPath;
std::string imgPath, imgDir, imgName;
int numThread = 4;
int loopCount = 1;
int padding = 0;
int maxSideLen = 1024;
float boxScoreThresh = 0.5f;
float boxThresh = 0.3f;
float unClipRatio = 2.0f;
bool doAngle = true;
int flagDoAngle = 1;
bool mostAngle = true;
int flagMostAngle = 1;
int opt;
int optionIndex = 0;
while ((opt = getopt_long(argc, argv, "d:1:2:3:4:i:t:p:s:b:o:u:a:A:v:h:l", long_options, &optionIndex)) != -1) {
//printf("option(-%c)=%s\n", opt, optarg);
switch (opt) {
case 'd':
modelsDir = optarg;
printf("modelsPath=%s\n", modelsDir.c_str());
break;
case '1':
modelDetPath = modelsDir + "/" + optarg;
printf("model det path=%s\n", modelDetPath.c_str());
break;
case '2':
modelClsPath = modelsDir + "/" + optarg;
printf("model cls path=%s\n", modelClsPath.c_str());
break;
case '3':
modelRecPath = modelsDir + "/" + optarg;
printf("model rec path=%s\n", modelRecPath.c_str());
break;
case '4':
keysPath = modelsDir + "/" + optarg;
printf("keys path=%s\n", keysPath.c_str());
break;
case 'i':
imgPath.assign(optarg);
imgDir.assign(imgPath.substr(0, imgPath.find_last_of('/') + 1));
imgName.assign(imgPath.substr(imgPath.find_last_of('/') + 1));
printf("imgDir=%s, imgName=%s\n", imgDir.c_str(), imgName.c_str());
break;
case 't':
numThread = (int) strtol(optarg, NULL, 10);
//printf("numThread=%d\n", numThread);
break;
case 'p':
padding = (int) strtol(optarg, NULL, 10);
//printf("padding=%d\n", padding);
break;
case 's':
maxSideLen = (int) strtol(optarg, NULL, 10);
//printf("maxSideLen=%d\n", maxSideLen);
break;
case 'b':
boxScoreThresh = strtof(optarg, NULL);
//printf("boxScoreThresh=%f\n", boxScoreThresh);
break;
case 'o':
boxThresh = strtof(optarg, NULL);
//printf("boxThresh=%f\n", boxThresh);
break;
case 'u':
unClipRatio = strtof(optarg, NULL);
//printf("unClipRatio=%f\n", unClipRatio);
break;
case 'a':
flagDoAngle = (int) strtol(optarg, NULL, 10);
if (flagDoAngle == 0) {
doAngle = false;
} else {
doAngle = true;
}
//printf("doAngle=%d\n", doAngle);
break;
case 'A':
flagMostAngle = (int) strtol(optarg, NULL, 10);
if (flagMostAngle == 0) {
mostAngle = false;
} else {
mostAngle = true;
}
//printf("mostAngle=%d\n", mostAngle);
break;
case 'v':
printf("%s\n", VERSION);
return 0;
case 'h':
printHelp(stdout, argv[0]);
return 0;
case 'l':
loopCount = (int) strtol(optarg, NULL, 10);
//printf("loopCount=%d\n", loopCount);
break;
default:
printf("other option %c :%s\n", opt, optarg);
}
}
bool hasTargetImgFile = isFileExists(imgPath);
if (!hasTargetImgFile) {
fprintf(stderr, "Target image not found: %s\n", imgPath.c_str());
return -1;
}
bool hasModelDetFile = isFileExists(modelDetPath);
if (!hasModelDetFile) {
fprintf(stderr, "Model det file not found: %s\n", modelDetPath.c_str());
return -1;
}
bool hasModelClsFile = isFileExists(modelClsPath);
if (!hasModelClsFile) {
fprintf(stderr, "Model cls file not found: %s\n", modelClsPath.c_str());
return -1;
}
bool hasModelRecFile = isFileExists(modelRecPath);
if (!hasModelRecFile) {
fprintf(stderr, "Model rec file not found: %s\n", modelRecPath.c_str());
return -1;
}
bool hasKeysFile = isFileExists(keysPath);
if (!hasKeysFile) {
fprintf(stderr, "keys file not found: %s\n", keysPath.c_str());
return -1;
}
OcrLite ocrLite;
ocrLite.setNumThread(numThread);
ocrLite.initLogger(
false,//isOutputConsole
false,//isOutputPartImg
false);//isOutputResultImg
//ocrLite.enableResultTxt(imgDir.c_str(), imgName.c_str());
printf("=====Input Params=====\n");
printf(
"numThread(%d),padding(%d),maxSideLen(%d),boxScoreThresh(%f),boxThresh(%f),unClipRatio(%f),doAngle(%d),mostAngle(%d)\n",
numThread, padding, maxSideLen, boxScoreThresh, boxThresh, unClipRatio, doAngle, mostAngle);
ocrLite.initModels(modelDetPath, modelClsPath, modelRecPath, keysPath);
printf("=====warmup=====\n");
OcrResult result = ocrLite.detect(imgDir.c_str(), imgName.c_str(), padding, maxSideLen,
boxScoreThresh, boxThresh, unClipRatio, doAngle, mostAngle);
printf("dbNetTime(%f) detectTime(%f)\n", result.dbNetTime, result.detectTime);
double dbTime = 0.0f;
double detectTime = 0.0f;
for (int i = 0; i < loopCount; ++i) {
printf("=====loop:%d=====\n", i + 1);
OcrResult ocrResult = ocrLite.detect(imgDir.c_str(), imgName.c_str(),
padding, maxSideLen,
boxScoreThresh, boxThresh,
unClipRatio, doAngle, mostAngle);
printf("dbNetTime(%f) detectTime(%f)\n", ocrResult.dbNetTime, ocrResult.detectTime);
dbTime += ocrResult.dbNetTime;
detectTime += ocrResult.detectTime;
}
printf("=====result=====\n");
printf("average dbNetTime=%fms, average detectTime=%fms\n", dbTime / loopCount,
detectTime / loopCount);
return 0;
}
@ECHO OFF
chcp 65001
cls
@SETLOCAL
mkdir win-BIN-x64
pushd win-BIN-x64
cmake -T "v142,host=x64" -A "x64" ^
-DCMAKE_INSTALL_PREFIX=install ^
-DCMAKE_BUILD_TYPE=Release -DOCR_OUTPUT="BIN" -DOCR_BUILD_CRT="True" ..
cmake --build . --config Release -j %NUMBER_OF_PROCESSORS%
cmake --build . --config Release --target install
popd
mkdir win-BIN-Win32
pushd win-BIN-Win32
cmake -T "v142,host=x64" -A "Win32" ^
-DCMAKE_INSTALL_PREFIX=install ^
-DCMAKE_BUILD_TYPE=Release -DOCR_OUTPUT="BIN" -DOCR_BUILD_CRT="True" ..
cmake --build . --config Release -j %NUMBER_OF_PROCESSORS%
cmake --build . --config Release --target install
popd
mkdir win-JNI-x64
pushd win-JNI-x64
cmake -T "v142,host=x64" -A "x64" ^
-DCMAKE_INSTALL_PREFIX=install ^
-DCMAKE_BUILD_TYPE=Release -DOCR_OUTPUT="JNI" -DOCR_BUILD_CRT="True" ..
cmake --build . --config Release -j %NUMBER_OF_PROCESSORS%
cmake --build . --config Release --target install
popd
mkdir win-JNI-Win32
pushd win-JNI-Win32
cmake -T "v142,host=x64" -A "Win32" ^
-DCMAKE_INSTALL_PREFIX=install ^
-DCMAKE_BUILD_TYPE=Release -DOCR_OUTPUT="JNI" -DOCR_BUILD_CRT="True" ..
cmake --build . --config Release -j %NUMBER_OF_PROCESSORS%
cmake --build . --config Release --target install
popd
mkdir win-CLIB-x64
pushd win-CLIB-x64
cmake -T "v142,host=x64" -A "x64" ^
-DCMAKE_INSTALL_PREFIX=install ^
-DCMAKE_BUILD_TYPE=Release -DOCR_OUTPUT="CLIB" -DOCR_BUILD_CRT="True" ..
cmake --build . --config Release -j %NUMBER_OF_PROCESSORS%
cmake --build . --config Release --target install
popd
mkdir win-CLIB-Win32
pushd win-CLIB-Win32
cmake -T "v142,host=x64" -A "Win32" ^
-DCMAKE_INSTALL_PREFIX=install ^
-DCMAKE_BUILD_TYPE=Release -DOCR_OUTPUT="CLIB" -DOCR_BUILD_CRT="True" ..
cmake --build . --config Release -j %NUMBER_OF_PROCESSORS%
cmake --build . --config Release --target install
popd
@ENDLOCAL
#!/usr/bin/env bash
sysOS=$(uname -s)
NUM_THREADS=1
if [ $sysOS == "Darwin" ]; then
#echo "I'm MacOS"
NUM_THREADS=$(sysctl -n hw.nCPU)
elif [ $sysOS == "Linux" ]; then
#echo "I'm Linux"
NUM_THREADS=$(grep ^processor /proc/cpuinfo | wc -l)
else
echo "Other OS: $sysOS"
fi
mkdir -p ${sysOS}-BIN
pushd ${sysOS}-BIN
cmake -DCMAKE_INSTALL_PREFIX=install -DCMAKE_BUILD_TYPE=Release -DOCR_OUTPUT="BIN" ..
cmake --build . --config Release -j $NUM_THREADS
cmake --build . --config Release --target install
popd
mkdir -p ${sysOS}-JNI
pushd ${sysOS}-JNI
cmake -DCMAKE_INSTALL_PREFIX=install -DCMAKE_BUILD_TYPE=Release -DOCR_OUTPUT="JNI" ..
cmake --build . --config Release -j $NUM_THREADS
cmake --build . --config Release --target install
popd
mkdir -p ${sysOS}-CLIB
pushd ${sysOS}-CLIB
cmake -DCMAKE_INSTALL_PREFIX=install -DCMAKE_BUILD_TYPE=Release -DOCR_OUTPUT="CLIB" ..
cmake --build . --config Release -j $NUM_THREADS
cmake --build . --config Release --target install
popd
@ECHO OFF
chcp 65001
cls
@SETLOCAL
echo "========请先参考README.md准备好编译环境========"
echo.
echo "========编译选项========"
echo "请注意:项目默认使用Release库,除非您自行编译Debug版的Onnxruntime和Opencv,否则请不要选择Debug编译"
echo "请输入编译选项并回车: 1)Release, 2)Debug"
set BUILD_TYPE=Release
set /p flag=
if %flag% == 1 (set BUILD_TYPE=Release)^
else if %flag% == 2 (set BUILD_TYPE=Debug)^
else (echo 输入错误!Input Error!)
echo.
echo "请注意:如果选择2)JNI动态库时,必须安装配置Oracle JDK"
echo "请选择编译输出类型并回车: 1)BIN可执行文件,2)JNI动态库,3)C动态库"
set /p flag=
if %flag% == 1 (set BUILD_OUTPUT="BIN")^
else if %flag% == 2 (set BUILD_OUTPUT="JNI")^
else if %flag% == 3 (set BUILD_OUTPUT="CLIB")^
else (echo 输入错误!Input Error!)
echo.
echo "引用库类型: 1)静态CRT(mt), 2)动态CRT(md)"
echo "注意:范例工程默认集成mt版库"
set /p flag=
if %flag% == 1 (
set MT_ENABLED="True"
)^
else (set MT_ENABLED="False")
echo.
echo "VS版本: 1)vs2019-x64, 2)vs2019-x86"
set BUILD_CMAKE_T="v142"
set BUILD_CMAKE_A="x64"
set /p flag=
if %flag% == 1 (
set BUILD_CMAKE_T="v142"
set BUILD_CMAKE_A="x64"
)^
else if %flag% == 2 (
set BUILD_CMAKE_T="v142"
set BUILD_CMAKE_A="Win32"
)^
else (echo 输入错误!Input Error!)
echo.
mkdir win-%BUILD_OUTPUT%-%BUILD_CMAKE_A%
pushd win-%BUILD_OUTPUT%-%BUILD_CMAKE_A%
cmake -T "%BUILD_CMAKE_T%,host=x64" -A %BUILD_CMAKE_A% ^
-DCMAKE_INSTALL_PREFIX=install ^
-DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DOCR_OUTPUT=%BUILD_OUTPUT% ^
-DOCR_BUILD_CRT=%MT_ENABLED% ..
cmake --build . --config %BUILD_TYPE% -j %NUMBER_OF_PROCESSORS%
cmake --build . --config %BUILD_TYPE% --target install
popd
GOTO:EOF
@ENDLOCAL
#!/usr/bin/env bash
echo "========请先参考README.md准备好编译环境========"
echo
echo "========编译选项========"
echo "请输入编译选项并回车: 1)Release, 2)Debug"
read -p "" BUILD_TYPE
if [ $BUILD_TYPE == 1 ]; then
BUILD_TYPE=Release
elif [ $BUILD_TYPE == 2 ]; then
BUILD_TYPE=Debug
else
echo -e "输入错误!Input Error!"
fi
echo "请注意:如果选择2)JNI动态库时,必须安装配置Oracle JDK"
echo "请选择编译输出类型并回车: 1)BIN可执行文件,2)JNI动态库,3)C动态库"
read -p "" BUILD_OUTPUT
if [ $BUILD_OUTPUT == 1 ]; then
BUILD_OUTPUT="BIN"
elif [ $BUILD_OUTPUT == 2 ]; then
BUILD_OUTPUT="JNI"
elif [ $BUILD_OUTPUT == 3 ]; then
BUILD_OUTPUT="CLIB"
else
echo -e "输入错误!Input Error!"
fi
sysOS=$(uname -s)
NUM_THREADS=1
if [ $sysOS == "Darwin" ]; then
#echo "I'm MacOS"
NUM_THREADS=$(sysctl -n hw.ncpu)
elif [ $sysOS == "Linux" ]; then
#echo "I'm Linux"
NUM_THREADS=$(grep ^processor /proc/cpuinfo | wc -l)
else
echo "Other OS: $sysOS"
fi
mkdir -p $sysOS-$BUILD_OUTPUT
pushd $sysOS-$BUILD_OUTPUT
echo "cmake -DCMAKE_INSTALL_PREFIX=install -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DOCR_OUTPUT=$BUILD_OUTPUT .."
cmake -DCMAKE_INSTALL_PREFIX=install -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DOCR_OUTPUT=$BUILD_OUTPUT ..
cmake --build . --config $BUILD_TYPE -j $NUM_THREADS
cmake --build . --config $BUILD_TYPE --target install
popd
@ECHO OFF
chcp 65001
cls
@SETLOCAL
echo "========请先参考README.md准备好编译环境========"
echo.
echo "========编译选项========"
echo "请注意:项目默认使用Release库,除非您自行编译Debug版的Onnxruntime和Opencv,否则请不要选择Debug编译"
echo "请输入编译选项并回车: 1)Release, 2)Debug"
set BUILD_TYPE=Release
set /p flag=
if %flag% == 1 (set BUILD_TYPE=Release)^
else if %flag% == 2 (set BUILD_TYPE=Debug)^
else (echo 输入错误!Input Error!)
echo.
echo "请注意:如果选择2)JNI动态库时,必须安装配置Oracle JDK"
echo "请选择编译输出类型并回车: 1)BIN可执行文件,2)JNI动态库,3)C动态库"
set /p flag=
if %flag% == 1 (set BUILD_OUTPUT="BIN")^
else if %flag% == 2 (set BUILD_OUTPUT="JNI")^
else if %flag% == 3 (set BUILD_OUTPUT="CLIB")^
else (echo 输入错误!Input Error!)
echo.
echo "引用的库类型: 1)静态CRT(mt), 2)动态CRT(md)"
echo "注意:范例工程默认集成mt版库"
set /p flag=
if %flag% == 1 (
set MT_ENABLED="True"
)^
else (set MT_ENABLED="False")
echo.
echo "请输入选项并回车: 0)ALL, 1)vs2019-x86, 2)vs2019-x64:"
set /p flag=
if %flag% == 0 (call :buildALL)^
else if %flag% == 1 (call :gen2019-x86)^
else if %flag% == 2 (call :gen2019-x64)^
else (echo "输入错误!Input Error!")
GOTO:EOF
:buildALL
call :gen2019-x86
call :gen2019-x64
GOTO:EOF
:gen2019-x86
mkdir build-win-vs2019-x86
pushd build-win-vs2019-x86
call :cmakeParams "Visual Studio 16 2019" "Win32"
popd
GOTO:EOF
:gen2019-x64
mkdir build-win-vs2019-x64
pushd build-win-vs2019-x64
call :cmakeParams "Visual Studio 16 2019" "x64"
popd
GOTO:EOF
:cmakeParams
echo cmake -G "%~1" -A "%~2" -DOCR_OUTPUT=%BUILD_OUTPUT% -DOCR_BUILD_CRT=%MT_ENABLED% ..
cmake -G "%~1" -A "%~2" -DOCR_OUTPUT=%BUILD_OUTPUT% -DOCR_BUILD_CRT=%MT_ENABLED% ..
GOTO:EOF
@ENDLOCAL
@ECHO OFF
echo Delete part img
DEL /Q *-part-*.jpg
echo Delete angle img
DEL /Q *-angle-*.jpg
echo Delete debug img
DEL /Q *-debug-*.jpg
echo Delete result img
DEL /Q *-result.jpg
echo Delete result txt
DEL /Q *-result.txt
#!/bin/bash
echo Delete part img
rm -f *-part-*.jpg
echo Delete angle img
rm -f *-angle-*.jpg
echo Delete debug img
rm -f *-debug-*.jpg
echo Delete result img
rm -f *-result.jpg
echo Delete result txt
rm -f *-result.txt
#ifndef __OCR_ANGLENET_H__
#define __OCR_ANGLENET_H__
#include "OcrStruct.h"
#include <onnxruntime/core/session/onnxruntime_cxx_api.h>
#include <opencv2/opencv.hpp>
class AngleNet {
public:
AngleNet();
~AngleNet();
void setNumThread(int numOfThread);
void initModel(const std::string &pathStr);
std::vector<Angle> getAngles(std::vector<cv::Mat> &partImgs, const char *path,
const char *imgName, bool doAngle, bool mostAngle);
private:
bool isOutputAngleImg = false;
Ort::Session *session;
Ort::Env env = Ort::Env(ORT_LOGGING_LEVEL_ERROR, "AngleNet");
Ort::SessionOptions sessionOptions = Ort::SessionOptions();
int numThread = 0;
std::vector<char *> inputNames;
std::vector<char *> outputNames;
const float meanValues[3] = {127.5, 127.5, 127.5};
const float normValues[3] = {1.0 / 127.5, 1.0 / 127.5, 1.0 / 127.5};
const int dstWidth = 192;
const int dstHeight = 48;
Angle getAngle(cv::Mat &src);
};
#endif //__OCR_ANGLENET_H__
#ifndef __OCR_CRNNNET_H__
#define __OCR_CRNNNET_H__
#include "OcrStruct.h"
#include <onnxruntime/core/session/onnxruntime_cxx_api.h>
#include <opencv2/opencv.hpp>
class CrnnNet {
public:
CrnnNet();
~CrnnNet();
void setNumThread(int numOfThread);
void initModel(const std::string &pathStr, const std::string &keysPath);
std::vector<TextLine> getTextLines(std::vector<cv::Mat> &partImg, const char *path, const char *imgName);
private:
bool isOutputDebugImg = false;
Ort::Session *session;
Ort::Env env = Ort::Env(ORT_LOGGING_LEVEL_ERROR, "CrnnNet");
Ort::SessionOptions sessionOptions = Ort::SessionOptions();
int numThread = 0;
std::vector<char *> inputNames;
std::vector<char *> outputNames;
const float meanValues[3] = {127.5, 127.5, 127.5};
const float normValues[3] = {1.0 / 127.5, 1.0 / 127.5, 1.0 / 127.5};
const int dstHeight = 32;
std::vector<std::string> keys;
TextLine scoreToTextLine(const std::vector<float> &outputData, int h, int w);
TextLine getTextLine(const cv::Mat &src);
};
#endif //__OCR_CRNNNET_H__
#ifndef __OCR_DBNET_H__
#define __OCR_DBNET_H__
#include "OcrStruct.h"
#include <onnxruntime/core/session/onnxruntime_cxx_api.h>
#include <opencv2/opencv.hpp>
class DbNet {
public:
DbNet();
~DbNet();
void setNumThread(int numOfThread);
void initModel(const std::string &pathStr);
std::vector<TextBox> getTextBoxes(cv::Mat &src, ScaleParam &s, float boxScoreThresh,
float boxThresh, float unClipRatio);
private:
Ort::Session *session;
Ort::Env env = Ort::Env(ORT_LOGGING_LEVEL_ERROR, "DbNet");
Ort::SessionOptions sessionOptions = Ort::SessionOptions();
int numThread = 0;
std::vector<char *> inputNames;
std::vector<char *> outputNames;
const float meanValues[3] = {0.485 * 255, 0.456 * 255, 0.406 * 255};
const float normValues[3] = {1.0 / 0.229 / 255.0, 1.0 / 0.224 / 255.0, 1.0 / 0.225 / 255.0};
};
#endif //__OCR_DBNET_H__
#ifndef __OCR_LITE_H__
#define __OCR_LITE_H__
#include "opencv2/core.hpp"
#include <onnxruntime/core/session/onnxruntime_cxx_api.h>
#include "OcrStruct.h"
#include "DbNet.h"
#include "AngleNet.h"
#include "CrnnNet.h"
class OcrLite {
public:
OcrLite();
~OcrLite();
void setNumThread(int numOfThread);
void initLogger(bool isConsole, bool isPartImg, bool isResultImg);
void enableResultTxt(const char *path, const char *imgName);
bool initModels(const std::string &detPath, const std::string &clsPath,
const std::string &recPath, const std::string &keysPath);
void Logger(const char *format, ...);
OcrResult detect(const char *path, const char *imgName,
int padding, int maxSideLen,
float boxScoreThresh, float boxThresh, float unClipRatio, bool doAngle, bool mostAngle);
OcrResult detect(const cv::Mat &mat,
int padding, int maxSideLen,
float boxScoreThresh, float boxThresh, float unClipRatio, bool doAngle, bool mostAngle);
private:
bool isOutputConsole = false;
bool isOutputPartImg = false;
bool isOutputResultTxt = false;
bool isOutputResultImg = false;
FILE *resultTxt;
DbNet dbNet;
AngleNet angleNet;
CrnnNet crnnNet;
std::vector<cv::Mat> getPartImages(cv::Mat &src, std::vector<TextBox> &textBoxes,
const char *path, const char *imgName);
OcrResult detect(const char *path, const char *imgName,
cv::Mat &src, cv::Rect &originRect, ScaleParam &scale,
float boxScoreThresh = 0.6f, float boxThresh = 0.3f,
float unClipRatio = 2.0f, bool doAngle = true, bool mostAngle = true);
};
#endif //__OCR_LITE_H__
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment