Skip to content

Commit

Permalink
init project and use mnn
Browse files Browse the repository at this point in the history
  • Loading branch information
thomaszheng committed Mar 23, 2021
0 parents commit 73bde7f
Show file tree
Hide file tree
Showing 41 changed files with 13,760 additions and 0 deletions.
142 changes: 142 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# 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/
opencv-static/
opencv-shared/
mnn-static/
mnn-shared/
.vscode/
126 changes: 126 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
cmake_minimum_required(VERSION 3.1)
project(OcrLiteMnn)

option(OCR_LIB "OcrLite Jni Support" OFF)
option(OCR_STATIC "Use Static Librarys For Build" ON)
option(OCR_BENCHMARK "build benchmark" ON)
#set(OCR_LIB ON)
#set(OCR_STATIC OFF)
set(OCR_BENCHMARK ON)

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 ()

# OpenMP flags for MACOS
if (APPLE)
if (CMAKE_C_COMPILER_ID MATCHES "Clang")
set(OpenMP_C "${CMAKE_C_COMPILER}")
set(OpenMP_C_FLAGS "-Xpreprocessor -fopenmp -I/usr/local/opt/libomp/include")
set(OpenMP_C_LIB_NAMES "omp")
set(OpenMP_omp_LIBRARY ${OpenMP_C_LIB_NAMES})
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(OpenMP_CXX "${CMAKE_CXX_COMPILER}")
set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -I/usr/local/opt/libomp/include")
set(OpenMP_CXX_LIB_NAMES "omp")
set(OpenMP_omp_LIBRARY ${OpenMP_C_LIB_NAMES})
endif ()
link_directories("/usr/local/opt/libomp/lib")
endif ()

# OpenMP
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}")
else ()
message(FATAL_ERROR "OpenMP Not Found!")
endif ()


# MNN
if (OCR_STATIC)
set(MNN_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mnn-static")
else ()
set(MNN_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mnn-shared")
endif ()
find_package(MNN REQUIRED)
if (MNN_FOUND)
message(STATUS "MNN_LIBS: ${MNN_LIBS}")
message(STATUS "MNN_INCLUDE_DIRS: ${MNN_INCLUDE_DIRS}")
else ()
message(FATAL_ERROR "MNN Not Found!")
endif (MNN_FOUND)


# OpenCV
if (OCR_STATIC)
include(${CMAKE_CURRENT_SOURCE_DIR}/opencv-static/OpenCVWrapperConfig.cmake)
else ()
include(${CMAKE_CURRENT_SOURCE_DIR}/opencv-shared/OpenCVWrapperConfig.cmake)
endif ()
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)

# JNI
if (OCR_LIB)
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 ()

# 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})

# static libgcc libstdc++
if (OCR_STATIC)
if (APPLE)
set(CMAKE_EXE_LINKER_FLAGS "-static-libstdc++")
else ()
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
endif ()
endif ()

if (OCR_LIB)
add_library(OcrLiteMnn SHARED ${OCR_COMPILE_CODE})
target_compile_definitions(OcrLiteMnn PRIVATE __JNI__)
target_link_libraries(OcrLiteMnn ${MNN_LIBS} ${OpenCV_LIBS} ${JNI_LIBS} ${OpenMP_CXX_LIB_NAMES})
else ()
add_executable(OcrLiteMnn ${OCR_COMPILE_CODE})
target_link_libraries(OcrLiteMnn ${MNN_LIBS} ${OpenCV_LIBS} ${OpenMP_CXX_LIB_NAMES})
endif ()

# benchmark
if (OCR_BENCHMARK AND NOT OCR_LIB)
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 ${MNN_LIBS} ${OpenCV_LIBS} ${OpenMP_CXX_LIB_NAMES})
endif ()
89 changes: 89 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
### 介绍

ChineseOcr Lite Mnn,超轻量级中文OCR PC Demo,使用MNN推理

这个项目使用MNN框架进行推理,使用 [https://github.com/ouyanghuiyu/chineseocr_lite](https://github.com/ouyanghuiyu/chineseocr_lite) 项目中提供的模型,迁移了项目中cpp_projects中的[OcrLiteOnnx](https://github.com/DayBreak-u/chineseocr_lite/tree/onnx/cpp_projects/OcrLiteOnnx)项目,采用阿里MNN框架[https://github.com/alibaba/MNN](https://github.com/alibaba/MNN) 作为推理引擎实现。


### 依赖的第三方库下载

下载opencv和MNN

* OpenCv动态库:opencv-(版本号)-sharedLib.7z
* OpenCv静态库:opencv-(版本号)-staticLib.7z
* MNN 动态库:Mnn-(版本号)-sharedLib.7z
* MNN 静态库:Mnn-(版本号)-staticLib.7z
* 可以选择只下载两者的动态库或两者的静态库(要么都是静态库要么都是动态库),或者4种全部下载
* 把压缩包解压到项目根目录,解压后目录结构

```
OcrLiteOnnx
├── mnn-shared
├── mnn-static
├── opencv-shared
├── opencv-static
```

### 编译环境

2. macOS 10.15

**注意:以下说明仅适用于本机编译。如果需要交叉编译为arm等其它平台(参考android),则需要先交叉编译所有第三方依赖库(mnn、opencv),然后再把依赖库整合替换到本项目里。**

### Mac编译说明

1. macOS Catalina 10.15.x,安装Xcode 12.1,并安装Xcode Command Line Tools, 终端运行```xcode-select –install```
2. 自行下载安装HomeBrew,cmake >=3.1[下载地址](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



### 编译参数说明

build.sh编译参数:

2. ```OCR_LIB=ON```: 启用(ON)或禁用(OFF) ON时编译为jni lib,OFF时编译为可执行文件
3. ```OCR_STATIC=ON```: 启用(ON)或禁用(OFF) ON时选择opencv和onnxruntime的静态库进行编译,OFF时则选择动态库编译

### 输入参数说明

* 请参考main.h中的命令行参数说明。
* 每个参数有一个短参数名和一个长参数名,用短的或长的均可。

1. ```-d或--models```:模型所在文件夹路径,可以相对路径也可以绝对路径。
2. ```-1或--det```:dbNet模型文件名(含扩展名)
3. ```-2或--cls```:angleNet模型文件名(含扩展名)
4. ```-3或--rec```:crnnNet模型文件名(含扩展名)
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编译)。
* valgrind-memcheck.txt是demo在linux平台的检查报告。
* 报告中的"possibly lost"均发生在第三方库,possibly lost可能不一定是泄露,暂时不管。
Loading

0 comments on commit 73bde7f

Please sign in to comment.