ncnn-ocr 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. ncnn_ocr-0.1.0/.github/scripts/build_ncnn.sh +23 -0
  2. ncnn_ocr-0.1.0/.github/scripts/set_version_from_tag.sh +22 -0
  3. ncnn_ocr-0.1.0/.github/workflows/ci.yml +99 -0
  4. ncnn_ocr-0.1.0/.github/workflows/release.yml +163 -0
  5. ncnn_ocr-0.1.0/.gitignore +33 -0
  6. ncnn_ocr-0.1.0/CMakeLists.txt +83 -0
  7. ncnn_ocr-0.1.0/LICENSE +21 -0
  8. ncnn_ocr-0.1.0/PKG-INFO +197 -0
  9. ncnn_ocr-0.1.0/README.md +171 -0
  10. ncnn_ocr-0.1.0/examples/basic.py +27 -0
  11. ncnn_ocr-0.1.0/native/bindings.cpp +109 -0
  12. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/clipper2/LICENSE +23 -0
  13. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/clipper2/clipper.core.h +1134 -0
  14. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/clipper2/clipper.engine.cpp +3161 -0
  15. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/clipper2/clipper.engine.h +635 -0
  16. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/clipper2/clipper.export.h +832 -0
  17. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/clipper2/clipper.h +795 -0
  18. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/clipper2/clipper.minkowski.h +117 -0
  19. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/clipper2/clipper.offset.cpp +661 -0
  20. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/clipper2/clipper.offset.h +125 -0
  21. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/clipper2/clipper.rectclip.cpp +1027 -0
  22. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/clipper2/clipper.rectclip.h +80 -0
  23. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/clipper2/clipper.version.h +6 -0
  24. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/json/LICENSE.MIT +21 -0
  25. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/json/json.hpp +25677 -0
  26. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Appenders/AndroidAppender.h +47 -0
  27. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Appenders/ArduinoAppender.h +23 -0
  28. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Appenders/ColorConsoleAppender.h +108 -0
  29. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Appenders/ConsoleAppender.h +83 -0
  30. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Appenders/DebugOutputAppender.h +16 -0
  31. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Appenders/DynamicAppender.h +42 -0
  32. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Appenders/EventLogAppender.h +117 -0
  33. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Appenders/IAppender.h +16 -0
  34. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Appenders/RollingFileAppender.h +148 -0
  35. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Converters/NativeEOLConverter.h +44 -0
  36. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Converters/UTF8Converter.h +28 -0
  37. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Formatters/CsvFormatter.h +57 -0
  38. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Formatters/FuncMessageFormatter.h +23 -0
  39. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Formatters/MessageOnlyFormatter.h +23 -0
  40. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Formatters/TxtFormatter.h +36 -0
  41. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Helpers/AscDump.h +40 -0
  42. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Helpers/HexDump.h +79 -0
  43. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Helpers/PrintVar.h +24 -0
  44. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Init.h +17 -0
  45. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Initializers/ConsoleInitializer.h +22 -0
  46. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Initializers/RollingFileInitializer.h +80 -0
  47. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/LICENSE +21 -0
  48. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Log.h +209 -0
  49. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Logger.h +84 -0
  50. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/README.md +1387 -0
  51. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Record.h +465 -0
  52. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Severity.h +61 -0
  53. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/Util.h +635 -0
  54. ncnn_ocr-0.1.0/native/paddleocr/3rdparty/plog/WinApi.h +175 -0
  55. ncnn_ocr-0.1.0/native/paddleocr/angle_net.cpp +146 -0
  56. ncnn_ocr-0.1.0/native/paddleocr/angle_net.h +50 -0
  57. ncnn_ocr-0.1.0/native/paddleocr/common.h +39 -0
  58. ncnn_ocr-0.1.0/native/paddleocr/config.h +50 -0
  59. ncnn_ocr-0.1.0/native/paddleocr/crnn_net.cpp +143 -0
  60. ncnn_ocr-0.1.0/native/paddleocr/crnn_net.h +52 -0
  61. ncnn_ocr-0.1.0/native/paddleocr/db_net.cpp +151 -0
  62. ncnn_ocr-0.1.0/native/paddleocr/db_net.h +51 -0
  63. ncnn_ocr-0.1.0/native/paddleocr/ocr_engine.cpp +267 -0
  64. ncnn_ocr-0.1.0/native/paddleocr/ocr_engine.h +53 -0
  65. ncnn_ocr-0.1.0/native/paddleocr/utils.cpp +195 -0
  66. ncnn_ocr-0.1.0/native/paddleocr/utils.h +26 -0
  67. ncnn_ocr-0.1.0/pyproject.toml +47 -0
  68. ncnn_ocr-0.1.0/scripts/build_wheel.sh +29 -0
  69. ncnn_ocr-0.1.0/src/ncnn_ocr/__init__.py +25 -0
  70. ncnn_ocr-0.1.0/src/ncnn_ocr/_ncnn_ocr.pyi +10 -0
  71. ncnn_ocr-0.1.0/src/ncnn_ocr/arabic.py +180 -0
  72. ncnn_ocr-0.1.0/src/ncnn_ocr/engine.py +162 -0
  73. ncnn_ocr-0.1.0/src/ncnn_ocr/lang.py +82 -0
  74. ncnn_ocr-0.1.0/src/ncnn_ocr/models.py +161 -0
  75. ncnn_ocr-0.1.0/src/ncnn_ocr/py.typed +0 -0
  76. ncnn_ocr-0.1.0/src/ncnn_ocr/types.py +41 -0
  77. ncnn_ocr-0.1.0/tests/test_arabic.py +41 -0
  78. ncnn_ocr-0.1.0/tests/test_integration.py +24 -0
  79. ncnn_ocr-0.1.0/tests/test_package.py +56 -0
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ NCNN_TAG="${NCNN_TAG:-20241226}"
5
+ NCNN_DIR="${NCNN_DIR:-$HOME/.local/ncnn}"
6
+ SRC_DIR="${RUNNER_TEMP:-/tmp}/ncnn-src"
7
+ BUILD_DIR="${RUNNER_TEMP:-/tmp}/ncnn-build"
8
+
9
+ if [[ -f "${NCNN_DIR}/lib/cmake/ncnn/ncnnConfig.cmake" ]]; then
10
+ echo "ncnn already installed at ${NCNN_DIR}"
11
+ exit 0
12
+ fi
13
+
14
+ git clone --depth 1 --branch "${NCNN_TAG}" https://github.com/Tencent/ncnn.git "${SRC_DIR}"
15
+ cmake -S "${SRC_DIR}" -B "${BUILD_DIR}" \
16
+ -DNCNN_VULKAN=OFF \
17
+ -DNCNN_BUILD_TOOLS=OFF \
18
+ -DNCNN_BUILD_EXAMPLES=OFF \
19
+ -DCMAKE_INSTALL_PREFIX="${NCNN_DIR}"
20
+ cmake --build "${BUILD_DIR}" -j"$(nproc)"
21
+ cmake --install "${BUILD_DIR}"
22
+
23
+ echo "NCNN_DIR=${NCNN_DIR}" >> "${GITHUB_ENV:-/dev/null}"
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ TAG="${GITHUB_REF_NAME:-}"
5
+ if [[ -z "$TAG" ]]; then
6
+ echo "GITHUB_REF_NAME is not set" >&2
7
+ exit 1
8
+ fi
9
+
10
+ VERSION="${TAG#v}"
11
+ if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+([a-zA-Z0-9.-]*)?$ ]]; then
12
+ echo "Invalid release tag: $TAG (expected vX.Y.Z)" >&2
13
+ exit 1
14
+ fi
15
+
16
+ echo "Setting package version to $VERSION"
17
+
18
+ sed -i.bak "s/^version = .*/version = \"$VERSION\"/" pyproject.toml
19
+ sed -i.bak "s/^__version__ = .*/__version__ = \"$VERSION\"/" src/ncnn_ocr/__init__.py
20
+ rm -f pyproject.toml.bak src/ncnn_ocr/__init__.py.bak
21
+
22
+ echo "PROJECT_VERSION=$VERSION" >> "${GITHUB_ENV:-/dev/null}"
@@ -0,0 +1,99 @@
1
+ name: CI
2
+
3
+ # Push to main / PRs: test + build wheels only. Does NOT publish to PyPI.
4
+ # PyPI publish happens only in release.yml on version tags (v*).
5
+
6
+ on:
7
+ push:
8
+ branches: [main, master]
9
+ pull_request:
10
+
11
+ env:
12
+ NCNN_TAG: "20241226"
13
+ NCNN_DIR: ${{ github.workspace }}/.ncnn
14
+
15
+ jobs:
16
+ test-python:
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - uses: actions/setup-python@v5
22
+ with:
23
+ python-version: "3.12"
24
+
25
+ - name: Install test dependencies
26
+ run: |
27
+ python -m pip install --upgrade pip
28
+ pip install pytest numpy opencv-python-headless huggingface-hub pillow
29
+
30
+ - name: Run unit tests
31
+ run: PYTHONPATH=src pytest -q tests/test_package.py tests/test_arabic.py
32
+
33
+ build-linux:
34
+ runs-on: ubuntu-latest
35
+ steps:
36
+ - uses: actions/checkout@v4
37
+
38
+ - name: Install system dependencies
39
+ run: |
40
+ sudo apt-get update
41
+ sudo apt-get install -y cmake libopencv-dev libomp-dev git
42
+
43
+ - name: Build and install ncnn
44
+ run: bash .github/scripts/build_ncnn.sh
45
+
46
+ - uses: actions/setup-python@v5
47
+ with:
48
+ python-version: "3.12"
49
+
50
+ - name: Build and test wheel
51
+ env:
52
+ CMAKE_PREFIX_PATH: ${{ env.NCNN_DIR }}
53
+ run: |
54
+ python -m pip install --upgrade pip build "scikit-build-core>=0.10" "pybind11>=2.11" pytest auditwheel
55
+ pip install numpy opencv-python-headless huggingface-hub pillow
56
+ python -m build --wheel
57
+ auditwheel repair dist/*.whl -w wheelhouse
58
+ rm -f dist/*.whl
59
+ mv wheelhouse/*.whl dist/
60
+ rmdir wheelhouse
61
+ pip install dist/*.whl
62
+ python -c "from ncnn_ocr import NATIVE_AVAILABLE; assert NATIVE_AVAILABLE"
63
+ pytest -q tests/test_integration.py
64
+
65
+ - uses: actions/upload-artifact@v4
66
+ with:
67
+ name: ci-wheel-linux-x86_64
68
+ path: dist/*.whl
69
+ retention-days: 7
70
+
71
+ build-macos:
72
+ runs-on: macos-14
73
+ steps:
74
+ - uses: actions/checkout@v4
75
+
76
+ - name: Install system dependencies
77
+ run: brew install cmake ncnn opencv@4 libomp
78
+
79
+ - uses: actions/setup-python@v5
80
+ with:
81
+ python-version: "3.12"
82
+
83
+ - name: Build and test wheel
84
+ env:
85
+ CMAKE_PREFIX_PATH: /opt/homebrew/opt/ncnn:/opt/homebrew/opt/opencv@4:/opt/homebrew/opt/libomp
86
+ OpenCV_DIR: /opt/homebrew/opt/opencv@4/lib/cmake/opencv4
87
+ run: |
88
+ python -m pip install --upgrade pip build "scikit-build-core>=0.10" "pybind11>=2.11" pytest
89
+ pip install numpy opencv-python-headless huggingface-hub pillow
90
+ python -m build --wheel
91
+ pip install dist/*.whl
92
+ python -c "from ncnn_ocr import NATIVE_AVAILABLE; assert NATIVE_AVAILABLE"
93
+ pytest -q tests/test_integration.py
94
+
95
+ - uses: actions/upload-artifact@v4
96
+ with:
97
+ name: ci-wheel-macos-arm64
98
+ path: dist/*.whl
99
+ retention-days: 7
@@ -0,0 +1,163 @@
1
+ name: Release
2
+
3
+ # PyPI publish ONLY on version tags (e.g. v0.1.0).
4
+ # Never runs on push to main — see ci.yml for build-only CI.
5
+
6
+ on:
7
+ push:
8
+ tags:
9
+ - "v*"
10
+
11
+ permissions:
12
+ contents: read
13
+ id-token: write
14
+
15
+ env:
16
+ NCNN_TAG: "20241226"
17
+ NCNN_DIR: ${{ github.workspace }}/.ncnn
18
+
19
+ jobs:
20
+ test:
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+
25
+ - uses: actions/setup-python@v5
26
+ with:
27
+ python-version: "3.12"
28
+
29
+ - name: Install test dependencies
30
+ run: |
31
+ python -m pip install --upgrade pip
32
+ pip install pytest numpy opencv-python-headless huggingface-hub pillow
33
+
34
+ - name: Run unit tests
35
+ run: PYTHONPATH=src pytest -q tests/test_package.py tests/test_arabic.py
36
+
37
+ build-linux:
38
+ runs-on: ubuntu-latest
39
+ steps:
40
+ - uses: actions/checkout@v4
41
+
42
+ - name: Set version from tag
43
+ run: bash .github/scripts/set_version_from_tag.sh
44
+
45
+ - name: Install system dependencies
46
+ run: |
47
+ sudo apt-get update
48
+ sudo apt-get install -y cmake libopencv-dev libomp-dev git
49
+
50
+ - name: Build and install ncnn
51
+ run: bash .github/scripts/build_ncnn.sh
52
+
53
+ - uses: actions/setup-python@v5
54
+ with:
55
+ python-version: "3.12"
56
+
57
+ - name: Build wheel
58
+ env:
59
+ CMAKE_PREFIX_PATH: ${{ env.NCNN_DIR }}
60
+ run: |
61
+ python -m pip install --upgrade pip build "scikit-build-core>=0.10" "pybind11>=2.11"
62
+ python -m build --wheel
63
+
64
+ - name: Repair wheel for PyPI (manylinux)
65
+ run: |
66
+ python -m pip install auditwheel
67
+ auditwheel repair dist/*.whl -w wheelhouse
68
+ rm -f dist/*.whl
69
+ mv wheelhouse/*.whl dist/
70
+ rmdir wheelhouse
71
+
72
+ - name: Smoke test wheel
73
+ run: |
74
+ pip install dist/*.whl opencv-python-headless huggingface-hub pillow pytest
75
+ python -c "from ncnn_ocr import OCR, NATIVE_AVAILABLE; assert NATIVE_AVAILABLE"
76
+ python -m pytest -q tests/test_integration.py
77
+
78
+ - uses: actions/upload-artifact@v4
79
+ with:
80
+ name: wheel-linux-x86_64
81
+ path: dist/*.whl
82
+
83
+ build-macos:
84
+ runs-on: macos-14
85
+ steps:
86
+ - uses: actions/checkout@v4
87
+
88
+ - name: Set version from tag
89
+ run: bash .github/scripts/set_version_from_tag.sh
90
+
91
+ - name: Install system dependencies
92
+ run: |
93
+ brew install cmake ncnn opencv@4 libomp
94
+
95
+ - uses: actions/setup-python@v5
96
+ with:
97
+ python-version: "3.12"
98
+
99
+ - name: Build wheel
100
+ env:
101
+ CMAKE_PREFIX_PATH: /opt/homebrew/opt/ncnn:/opt/homebrew/opt/opencv@4:/opt/homebrew/opt/libomp
102
+ OpenCV_DIR: /opt/homebrew/opt/opencv@4/lib/cmake/opencv4
103
+ run: |
104
+ python -m pip install --upgrade pip build "scikit-build-core>=0.10" "pybind11>=2.11"
105
+ python -m build --wheel
106
+
107
+ - name: Smoke test wheel
108
+ run: |
109
+ pip install dist/*.whl opencv-python-headless huggingface-hub pillow pytest
110
+ python -c "from ncnn_ocr import OCR, NATIVE_AVAILABLE; assert NATIVE_AVAILABLE"
111
+ python -m pytest -q tests/test_integration.py
112
+
113
+ - uses: actions/upload-artifact@v4
114
+ with:
115
+ name: wheel-macos-arm64
116
+ path: dist/*.whl
117
+
118
+ build-sdist:
119
+ runs-on: ubuntu-latest
120
+ steps:
121
+ - uses: actions/checkout@v4
122
+
123
+ - name: Set version from tag
124
+ run: bash .github/scripts/set_version_from_tag.sh
125
+
126
+ - uses: actions/setup-python@v5
127
+ with:
128
+ python-version: "3.12"
129
+
130
+ - name: Build sdist
131
+ run: |
132
+ python -m pip install --upgrade pip build "scikit-build-core>=0.10" "pybind11>=2.11"
133
+ python -m build --sdist
134
+
135
+ - uses: actions/upload-artifact@v4
136
+ with:
137
+ name: sdist
138
+ path: dist/*.tar.gz
139
+
140
+ publish-pypi:
141
+ name: Publish to PyPI
142
+ if: startsWith(github.ref, 'refs/tags/v')
143
+ needs: [test, build-linux, build-macos, build-sdist]
144
+ runs-on: ubuntu-latest
145
+ environment:
146
+ name: pypi
147
+ url: https://pypi.org/project/ncnn-ocr/
148
+ steps:
149
+ - name: Download artifacts
150
+ uses: actions/download-artifact@v4
151
+ with:
152
+ path: dist
153
+ merge-multiple: true
154
+
155
+ - name: List distributions
156
+ run: ls -lh dist/
157
+
158
+ - name: Publish to PyPI
159
+ uses: pypa/gh-action-pypi-publish@release/v1
160
+ with:
161
+ packages-dir: dist
162
+ print-hash: true
163
+ password: ${{ secrets.PYPI_API_TOKEN }}
@@ -0,0 +1,33 @@
1
+ # Byte-compiled / cache
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.so
5
+ *.dylib
6
+ *.pyd
7
+
8
+ # Build artifacts
9
+ build/
10
+ dist/
11
+ *.egg-info/
12
+ .scikit-build/
13
+ cmake-build-*/
14
+
15
+ # Virtual environments
16
+ .venv/
17
+ venv/
18
+
19
+ # IDE / OS
20
+ .DS_Store
21
+ .idea/
22
+ .vscode/
23
+
24
+ # Test / coverage
25
+ .pytest_cache/
26
+ .coverage
27
+ htmlcov/
28
+
29
+ # Downloaded models (local dev)
30
+ .models/
31
+
32
+ # Editor swap
33
+ *.swp
@@ -0,0 +1,83 @@
1
+ cmake_minimum_required(VERSION 3.20)
2
+ project(ncnn_ocr LANGUAGES CXX)
3
+
4
+ set(CMAKE_CXX_STANDARD 17)
5
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
6
+
7
+ if(NOT CMAKE_BUILD_TYPE)
8
+ set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
9
+ endif()
10
+
11
+ if(MSVC)
12
+ add_compile_options(/W4 /utf-8)
13
+ else()
14
+ add_compile_options(-Wall -Wextra -Wpedantic)
15
+ endif()
16
+
17
+ find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
18
+ find_package(pybind11 CONFIG REQUIRED)
19
+ find_package(OpenCV REQUIRED)
20
+
21
+ if(APPLE)
22
+ if(EXISTS "/opt/homebrew/opt/libomp/lib/libomp.dylib")
23
+ set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -I/opt/homebrew/opt/libomp/include")
24
+ set(OpenMP_CXX_LIB_NAMES "omp")
25
+ set(OpenMP_omp_LIBRARY "/opt/homebrew/opt/libomp/lib/libomp.dylib")
26
+ elseif(EXISTS "/usr/local/opt/libomp/lib/libomp.dylib")
27
+ set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -I/usr/local/opt/libomp/include")
28
+ set(OpenMP_CXX_LIB_NAMES "omp")
29
+ set(OpenMP_omp_LIBRARY "/usr/local/opt/libomp/lib/libomp.dylib")
30
+ endif()
31
+ endif()
32
+ find_package(OpenMP REQUIRED)
33
+
34
+ if(DEFINED ENV{NCNN_DIR} AND NOT ncnn_DIR)
35
+ set(ncnn_DIR "$ENV{NCNN_DIR}/lib/cmake/ncnn")
36
+ endif()
37
+ if(NOT ncnn_DIR)
38
+ foreach(_hint
39
+ "$ENV{NCNN_DIR}/lib/cmake/ncnn"
40
+ "$ENV{HOME}/.local/ncnn/lib/cmake/ncnn"
41
+ "/opt/homebrew/opt/ncnn/lib/cmake/ncnn"
42
+ "/usr/local/opt/ncnn/lib/cmake/ncnn"
43
+ "/usr/local/lib/cmake/ncnn")
44
+ if(EXISTS "${_hint}/ncnnConfig.cmake")
45
+ set(ncnn_DIR "${_hint}")
46
+ break()
47
+ endif()
48
+ endforeach()
49
+ endif()
50
+ find_package(ncnn REQUIRED)
51
+
52
+ set(PADDLEOCR_DIR "${CMAKE_CURRENT_SOURCE_DIR}/native/paddleocr")
53
+
54
+ set(NCNN_OCR_SOURCES
55
+ native/bindings.cpp
56
+ ${PADDLEOCR_DIR}/db_net.cpp
57
+ ${PADDLEOCR_DIR}/angle_net.cpp
58
+ ${PADDLEOCR_DIR}/crnn_net.cpp
59
+ ${PADDLEOCR_DIR}/ocr_engine.cpp
60
+ ${PADDLEOCR_DIR}/utils.cpp
61
+ ${PADDLEOCR_DIR}/3rdparty/clipper2/clipper.engine.cpp
62
+ ${PADDLEOCR_DIR}/3rdparty/clipper2/clipper.offset.cpp
63
+ ${PADDLEOCR_DIR}/3rdparty/clipper2/clipper.rectclip.cpp
64
+ )
65
+
66
+ pybind11_add_module(_ncnn_ocr MODULE ${NCNN_OCR_SOURCES})
67
+
68
+ target_include_directories(_ncnn_ocr PRIVATE
69
+ ${PADDLEOCR_DIR}
70
+ ${PADDLEOCR_DIR}/3rdparty
71
+ )
72
+
73
+ target_link_libraries(_ncnn_ocr PRIVATE
74
+ ${OpenCV_LIBS}
75
+ ncnn
76
+ OpenMP::OpenMP_CXX
77
+ )
78
+
79
+ if(WIN32)
80
+ target_compile_definitions(_ncnn_ocr PRIVATE NOMINMAX)
81
+ endif()
82
+
83
+ install(TARGETS _ncnn_ocr DESTINATION ncnn_ocr)
ncnn_ocr-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Avafly
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,197 @@
1
+ Metadata-Version: 2.2
2
+ Name: ncnn-ocr
3
+ Version: 0.1.0
4
+ Summary: High-performance OCR using PaddleOCR PP-OCR Mobile models on Tencent NCNN
5
+ Keywords: ocr,ncnn,paddleocr,pp-ocr,text-recognition
6
+ Author: Abu
7
+ License: Apache-2.0
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: Apache Software License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3 :: Only
13
+ Classifier: Topic :: Scientific/Engineering :: Image Recognition
14
+ Project-URL: Homepage, https://github.com/developerabu/py-ocr-ncnn
15
+ Project-URL: Repository, https://github.com/developerabu/py-ocr-ncnn
16
+ Project-URL: Documentation, https://github.com/developerabu/py-ocr-ncnn#readme
17
+ Requires-Python: >=3.10
18
+ Requires-Dist: numpy>=1.21
19
+ Requires-Dist: opencv-python-headless>=4.5
20
+ Requires-Dist: huggingface-hub>=0.20
21
+ Requires-Dist: pillow>=9.0
22
+ Provides-Extra: dev
23
+ Requires-Dist: pytest>=7; extra == "dev"
24
+ Requires-Dist: ruff>=0.4; extra == "dev"
25
+ Description-Content-Type: text/markdown
26
+
27
+ # ncnn-ocr
28
+
29
+ Production-ready Python OCR built on [PaddleOCR PP-OCR Mobile](https://github.com/PaddlePaddle/PaddleOCR) models running on [Tencent NCNN](https://github.com/Tencent/ncnn).
30
+
31
+ Standalone, publishable to PyPI, and independent of Qefro.
32
+
33
+ ## Features
34
+
35
+ - **Fast CPU inference** — NCNN-backed det + cls + rec pipeline (same engine as [PaddleOCR-ncnn-CPP](https://github.com/Avafly/PaddleOCR-ncnn-CPP))
36
+ - **PP-OCRv5 multilingual** — Tamil, Arabic, Devanagari, Latin, Korean, Cyrillic, and more
37
+ - **PP-OCRv6 profiles** — `v6_tiny`, `v6_small`, `v6_medium`
38
+ - **Simple API** — `recognize()`, `recognize_text()`, `batch()`
39
+ - **Auto model download** — pulls weights from [developerabu/pp-OCRv5-6-ncnn](https://huggingface.co/developerabu/pp-OCRv5-6-ncnn) on first use
40
+ - **Arabic post-processing** — optional visual-order → logical-order fix
41
+
42
+ ## Install
43
+
44
+ ### From source (requires native deps)
45
+
46
+ ```bash
47
+ # macOS (Homebrew)
48
+ brew install cmake opencv ncnn
49
+
50
+ # Debian/Ubuntu
51
+ sudo apt install cmake libopencv-dev libomp-dev
52
+
53
+ # Build ncnn if not packaged (see https://github.com/Tencent/ncnn)
54
+ export NCNN_DIR=$HOME/.local/ncnn # optional, CMake searches common paths
55
+
56
+ pip install .
57
+ ```
58
+
59
+ ### Python dependencies only (no extension)
60
+
61
+ Pure-Python modules import without the `_ncnn_ocr` extension; `OCR()` raises a clear error until the native module is built.
62
+
63
+ ## Quick start
64
+
65
+ ```python
66
+ from ncnn_ocr import OCR
67
+
68
+ ocr = OCR(lang="ta")
69
+ text = ocr.recognize_text("page.png")
70
+ print(text)
71
+
72
+ lines = ocr.recognize("page.png")
73
+ for line in lines:
74
+ print(line.text, line.confidence, line.box)
75
+ ```
76
+
77
+ One-shot helpers:
78
+
79
+ ```python
80
+ from ncnn_ocr import recognize_text
81
+
82
+ print(recognize_text("scan.jpg", lang="en"))
83
+ ```
84
+
85
+ ## Supported languages (PP-OCRv5)
86
+
87
+ | Code | Script / language |
88
+ |------|---------------------|
89
+ | `en` | English |
90
+ | `ta`, `te` | Tamil, Telugu |
91
+ | `hi`, `mr`, `ne` | Devanagari |
92
+ | `ar`, `fa`, `ur` | Arabic |
93
+ | `ko`, `th`, `el` | Korean, Thai, Greek |
94
+ | `ru`, `uk`, `bg` | Cyrillic / Slavic |
95
+ | `de`, `fr`, `es`, `latin` | Latin |
96
+ | `ch`, `zh` | Chinese (generic v5 rec) |
97
+
98
+ ```python
99
+ from ncnn_ocr import supported_langs
100
+ print(supported_langs())
101
+ ```
102
+
103
+ ## PP-OCRv6
104
+
105
+ ```python
106
+ ocr = OCR(lang="en", profile="v6_tiny")
107
+ text = ocr.recognize_text("page.png")
108
+ ```
109
+
110
+ Profiles: `v6_tiny`, `v6_small`, `v6_medium`.
111
+
112
+ ## Environment variables
113
+
114
+ | Variable | Default | Description |
115
+ |----------|---------|-------------|
116
+ | `NCNN_OCR_MODEL_DIR` | `~/.cache/ncnn-ocr/models` | Local model cache |
117
+ | `NCNN_OCR_HF_REPO` | `developerabu/pp-OCRv5-6-ncnn` | HuggingFace model repo |
118
+
119
+ ## Build layout
120
+
121
+ ```
122
+ py-ocr-ncnn/
123
+ ├── src/ncnn_ocr/ # Python package
124
+ ├── native/
125
+ │ ├── bindings.cpp # pybind11 wrapper
126
+ │ └── paddleocr/ # vendored NCNN OCR engine (Apache-2.0)
127
+ ├── CMakeLists.txt
128
+ └── pyproject.toml
129
+ ```
130
+
131
+ ## Models
132
+
133
+ On first run, recognition models and keys are downloaded from HuggingFace. Shared PP-OCRv5 detection and angle-classifier weights are fetched from HuggingFace when available, otherwise from the [PaddleOCR-ncnn-CPP v0.3.0 archive](https://github.com/Avafly/PaddleOCR-ncnn-CPP/releases/download/v0.3.0/archive.tar.gz).
134
+
135
+ ## Development
136
+
137
+ ```bash
138
+ python -m venv .venv && source .venv/bin/activate
139
+ pip install -e ".[dev]"
140
+ PYTHONPATH=src pytest -q
141
+ ```
142
+
143
+ ## Release to PyPI
144
+
145
+ | Event | Workflow | What happens |
146
+ |-------|----------|--------------|
147
+ | Push to `main` / PR | `ci.yml` | Tests + builds wheels (artifacts only, **no PyPI**) |
148
+ | Push tag `v*` | `release.yml` | Tests + builds wheels + **publishes to PyPI** |
149
+
150
+ Pushing a version tag triggers `.github/workflows/release.yml`, which:
151
+
152
+ 1. Runs unit tests
153
+ 2. Builds Linux (`x86_64`) and macOS (`arm64`) wheels plus an sdist
154
+ 3. Runs an integration OCR smoke test on each wheel
155
+ 4. Publishes all artifacts to PyPI
156
+
157
+ ### One-time PyPI setup
158
+
159
+ 1. Create a PyPI API token at [pypi.org/manage/account/token](https://pypi.org/manage/account/token/) scoped to `ncnn-ocr`
160
+ 2. Add it as a GitHub secret:
161
+ - Go to [github.com/qefro-ai/py-ocr-ncnn/settings/secrets/actions](https://github.com/qefro-ai/py-ocr-ncnn/settings/secrets/actions)
162
+ - **New repository secret**
163
+ - Name: **`PYPI_API_TOKEN`**
164
+ - Value: your `pypi-...` token
165
+ 3. Create GitHub environment **`pypi`** (Settings → Environments) — used by the release workflow
166
+
167
+ ### Cut a release
168
+
169
+ ```bash
170
+ git tag v0.1.0
171
+ git push origin v0.1.0
172
+ ```
173
+
174
+ The workflow reads the tag (`v0.1.0` → version `0.1.0`) and uploads:
175
+
176
+ - `ncnn_ocr-*-cp312-cp312-linux_x86_64.whl`
177
+ - `ncnn_ocr-*-cp312-cp312-macosx_*_arm64.whl`
178
+ - `ncnn_ocr-*.tar.gz`
179
+
180
+ ### Manual publish (fallback)
181
+
182
+ ```bash
183
+ bash scripts/build_wheel.sh
184
+ python -m twine upload dist/*
185
+ ```
186
+
187
+ Requires `TWINE_USERNAME=__token__` and `TWINE_PASSWORD` set to a PyPI API token.
188
+
189
+ ## License
190
+
191
+ Apache-2.0 — see [LICENSE](LICENSE). The vendored PaddleOCR-ncnn-CPP sources retain their original license.
192
+
193
+ ## Credits
194
+
195
+ - [Avafly/PaddleOCR-ncnn-CPP](https://github.com/Avafly/PaddleOCR-ncnn-CPP) — NCNN OCR engine
196
+ - [PaddleOCR](https://github.com/PaddlePaddle/PaddleOCR) — PP-OCR models
197
+ - [Tencent NCNN](https://github.com/Tencent/ncnn) — inference framework