fastbbox 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.
@@ -0,0 +1,122 @@
1
+ name: Build and Publish
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ tags:
7
+ - 'v*' # release: v1.2.3 → publish to PyPI
8
+ - 'v*-rc*' # candidate: v1.2.3-rc1 → publish to TestPyPI
9
+ pull_request:
10
+ branches: [ main ]
11
+ workflow_dispatch: # allow manual trigger from the Actions UI
12
+
13
+ jobs:
14
+ build_wheels:
15
+ name: Build wheels on ${{ matrix.os }}
16
+ runs-on: ${{ matrix.os }}
17
+ timeout-minutes: 30
18
+ strategy:
19
+ matrix:
20
+ os: [ubuntu-latest, windows-latest, macos-latest]
21
+
22
+ steps:
23
+ - uses: actions/checkout@v6
24
+
25
+ - name: Set up Python
26
+ uses: actions/setup-python@v5
27
+ with:
28
+ python-version: '3.11'
29
+
30
+ - name: Build wheels
31
+ uses: pypa/cibuildwheel@v2.21.0
32
+ env:
33
+ CIBW_BUILD: cp39-* cp310-* cp311-* cp312-*
34
+ # Skip 32-bit, PyPy, and musl builds
35
+ CIBW_SKIP: "*-win32 *-manylinux_i686 *-musllinux_* pp*"
36
+ # Use modern manylinux_2_28
37
+ CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28
38
+ CIBW_MANYLINUX_AARCH64_IMAGE: manylinux_2_28
39
+ # Install build dependencies
40
+ CIBW_BEFORE_BUILD: pip install nanobind scikit-build-core cmake ninja numpy
41
+ # Linux: Install C++ compiler and CMake
42
+ CIBW_BEFORE_ALL_LINUX: |
43
+ if command -v dnf >/dev/null; then
44
+ dnf install -y gcc-c++ cmake ninja-build
45
+ else
46
+ yum install -y gcc-c++ cmake ninja-build
47
+ fi
48
+ # Windows: Use delvewheel for repair
49
+ CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: pip install delvewheel && delvewheel repair -w {dest_dir} {wheel}
50
+ # Smoke test
51
+ CIBW_TEST_COMMAND: >-
52
+ python -c "from fastbbox import bbox_overlaps; import numpy as np;
53
+ boxes = np.array([[0,0,10,10]], dtype=np.float32);
54
+ result = bbox_overlaps(boxes, boxes);
55
+ assert result[0,0] > 0.99, 'IoU test failed';
56
+ print('fastbbox import OK')"
57
+ # nanobind requires macos 10.13 or higher
58
+ CIBW_ENVIRONMENT_MACOS: MACOSX_DEPLOYMENT_TARGET=10.13
59
+
60
+ - uses: actions/upload-artifact@v4
61
+ with:
62
+ name: wheels-${{ matrix.os }}
63
+ path: ./wheelhouse/*.whl
64
+
65
+ build_sdist:
66
+ name: Build source distribution
67
+ runs-on: ubuntu-latest
68
+ timeout-minutes: 15
69
+ steps:
70
+ - uses: actions/checkout@v4
71
+
72
+ - name: Build sdist
73
+ run: pipx run build --sdist
74
+
75
+ - uses: actions/upload-artifact@v4
76
+ with:
77
+ name: sdist
78
+ path: dist/*.tar.gz
79
+
80
+ upload_testpypi:
81
+ needs: [build_wheels, build_sdist]
82
+ runs-on: ubuntu-latest
83
+ timeout-minutes: 15
84
+ # Only on release-candidate tags: v1.2.3-rc1, v1.2.3-rc2, etc.
85
+ if: github.event_name == 'push' && contains(github.ref, '-rc')
86
+ environment:
87
+ name: testpypi
88
+ url: https://test.pypi.org/p/fastbbox
89
+ steps:
90
+ - name: Download all artifacts
91
+ uses: actions/download-artifact@v8
92
+ with:
93
+ path: dist
94
+ merge-multiple: true
95
+
96
+ - name: Publish to TestPyPI
97
+ run: |
98
+ pip install twine
99
+ twine upload --repository testpypi dist/*
100
+ env:
101
+ TWINE_USERNAME: __token__
102
+ TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
103
+
104
+ upload_pypi:
105
+ needs: [build_wheels, build_sdist]
106
+ runs-on: ubuntu-latest
107
+ timeout-minutes: 15
108
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
109
+ environment:
110
+ name: pypi
111
+ url: https://pypi.org/p/fastbbox
112
+ permissions:
113
+ id-token: write
114
+ steps:
115
+ - name: Download all artifacts
116
+ uses: actions/download-artifact@v8
117
+ with:
118
+ path: dist
119
+ merge-multiple: true
120
+
121
+ - name: Publish to PyPI
122
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,157 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+ *.pyd
9
+
10
+ # Distribution / packaging
11
+ .Python
12
+ build/
13
+ develop-eggs/
14
+ dist/
15
+ downloads/
16
+ eggs/
17
+ .eggs/
18
+ lib/
19
+ lib64/
20
+ parts/
21
+ sdist/
22
+ var/
23
+ wheels/
24
+ pip-wheel-metadata/
25
+ share/python-wheels/
26
+ *.egg-info/
27
+ .installed.cfg
28
+ *.egg
29
+ MANIFEST
30
+
31
+ # PyInstaller
32
+ # Usually these files are written by a python script from a template
33
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
34
+ *.manifest
35
+ *.spec
36
+
37
+ # Installer logs
38
+ pip-log.txt
39
+ pip-delete-this-directory.txt
40
+
41
+ # Unit test / coverage reports
42
+ htmlcov/
43
+ .tox/
44
+ .nox/
45
+ .coverage
46
+ .coverage.*
47
+ .cache
48
+ nosetests.xml
49
+ coverage.xml
50
+ *.cover
51
+ *.py,cover
52
+ .hypothesis/
53
+ .pytest_cache/
54
+
55
+ # Translations
56
+ *.mo
57
+ *.pot
58
+
59
+ # Django stuff:
60
+ *.log
61
+ local_settings.py
62
+ db.sqlite3
63
+ db.sqlite3-journal
64
+
65
+ # Flask stuff:
66
+ instance/
67
+ .webassets-cache
68
+
69
+ # Scrapy stuff:
70
+ .scrapy
71
+
72
+ # Sphinx documentation
73
+ docs/_build/
74
+
75
+ # PyBuilder
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ .python-version
87
+
88
+ # pipenv
89
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
90
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
91
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
92
+ # install all needed dependencies.
93
+ #Pipfile.lock
94
+
95
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
96
+ __pypackages__/
97
+
98
+ # Celery stuff
99
+ celerybeat-schedule
100
+ celerybeat.pid
101
+
102
+ # SageMath parsed files
103
+ *.sage.py
104
+
105
+ # Environments
106
+ .env
107
+ .venv
108
+ env/
109
+ venv/
110
+ ENV/
111
+ env.bak/
112
+ venv.bak/
113
+
114
+ # Spyder project settings
115
+ .spyderproject
116
+ .spyproject
117
+
118
+ # Rope project settings
119
+ .ropeproject
120
+
121
+ # mkdocs documentation
122
+ /site
123
+
124
+ # mypy
125
+ .mypy_cache/
126
+ .dmypy.json
127
+ dmypy.json
128
+
129
+ # Pyre type checker
130
+ .pyre/
131
+
132
+ # Exclude auto-generated C/C++ files
133
+ *.c
134
+ *.cpp
135
+ *.html
136
+ # Track nanobind C++ sources (intentional committed sources, not generated)
137
+ !src/fastbbox/*_nb.cpp
138
+
139
+ # IDE files
140
+ .vscode/
141
+ .idea/
142
+ *.swp
143
+ *.swo
144
+ *~
145
+
146
+ # OS files
147
+ .DS_Store
148
+ .DS_Store?
149
+ ._*
150
+ .Spotlight-V100
151
+ .Trashes
152
+ ehthumbs.db
153
+ Thumbs.db
154
+
155
+ # Temporary files
156
+ *.tmp
157
+ *.temp
@@ -0,0 +1,34 @@
1
+ cmake_minimum_required(VERSION 3.15...3.27)
2
+ project(fastbbox_nanobind LANGUAGES CXX)
3
+
4
+ # Detect Python with Development.Module component
5
+ if (CMAKE_VERSION VERSION_LESS 3.18)
6
+ set(DEV_MODULE Development)
7
+ else()
8
+ set(DEV_MODULE Development.Module)
9
+ endif()
10
+
11
+ find_package(Python 3.9 COMPONENTS Interpreter ${DEV_MODULE} REQUIRED)
12
+
13
+ # Configure optimized release build by default
14
+ if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
15
+ set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
16
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
17
+ endif()
18
+
19
+ # Detect the installed nanobind package and import it into CMake
20
+ execute_process(
21
+ COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir
22
+ OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE nanobind_ROOT)
23
+ find_package(nanobind CONFIG REQUIRED)
24
+
25
+ # Build bbox module
26
+ # Use NOMINSIZE since our binding layer contains significant computational logic
27
+ # that benefits from speed optimization rather than size optimization
28
+ nanobind_add_module(bbox NOMINSIZE ${CMAKE_CURRENT_SOURCE_DIR}/src/fastbbox/bbox_nb.cpp)
29
+
30
+ # Build obb_bbox module
31
+ nanobind_add_module(obb_bbox NOMINSIZE ${CMAKE_CURRENT_SOURCE_DIR}/src/fastbbox/obb_bbox_nb.cpp)
32
+
33
+ # Install the modules
34
+ install(TARGETS bbox obb_bbox LIBRARY DESTINATION fastbbox)
@@ -0,0 +1,6 @@
1
+ include README.md
2
+ include LICENSE
3
+ include CMakeLists.txt
4
+ recursive-include src/fastbbox *_nb.cpp
5
+ global-exclude *.pyc
6
+ global-exclude *.so
@@ -0,0 +1,214 @@
1
+ Metadata-Version: 2.2
2
+ Name: fastbbox
3
+ Version: 0.1.0
4
+ Summary: Fast IoU/overlap computations for bounding boxes
5
+ Author-Email: Gerry Lim <gerrylimwk@gmail.com>
6
+ License: MIT
7
+ Classifier: Development Status :: 4 - Beta
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: C++
16
+ Classifier: Topic :: Scientific/Engineering
17
+ Project-URL: Homepage, https://github.com/gerrylwk/fastbbox
18
+ Project-URL: Repository, https://github.com/gerrylwk/fastbbox
19
+ Project-URL: Issues, https://github.com/gerrylwk/fastbbox/issues
20
+ Requires-Python: >=3.9
21
+ Requires-Dist: numpy>=1.19.0
22
+ Provides-Extra: dev
23
+ Requires-Dist: pytest>=7.0; extra == "dev"
24
+ Requires-Dist: build>=0.10; extra == "dev"
25
+ Requires-Dist: scikit-build-core>=0.5.0; extra == "dev"
26
+ Requires-Dist: nanobind>=1.0.0; extra == "dev"
27
+ Requires-Dist: cmake>=3.15; extra == "dev"
28
+ Description-Content-Type: text/markdown
29
+
30
+ # FastBBox
31
+
32
+ Fast IoU/overlap computations for axis-aligned and oriented bounding boxes, powered by nanobind C++ extensions.
33
+
34
+ ## Benchmark
35
+ ```
36
+ Function Python (ms) FastBBox (ms) Speedup
37
+ --------------------------------------------------
38
+ IoU 1994.19 4.19 475.7x
39
+ GIoU 3028.40 5.99 505.8x
40
+ DIoU 4104.21 6.21 661.3x
41
+ CIoU 6436.51 17.55 366.7x
42
+ EIoU 5211.51 7.04 740.5x
43
+ NWD 2427.36 13.31 182.4x
44
+ OBB 21729.42 31.29 694.5x
45
+ --------------------------------------------------
46
+ TOTAL 44931.61 85.58 525.1x
47
+ ```
48
+
49
+ ## Installation
50
+
51
+ ```bash
52
+ pip install fastbbox
53
+ ```
54
+
55
+ ### Building from Source
56
+
57
+ Requires CMake 3.15+ and a C++17 compiler.
58
+
59
+ ```bash
60
+ git clone https://github.com/gerrylwk/fastbbox
61
+ cd fastbbox
62
+ pip install .
63
+ ```
64
+
65
+ ## Usage
66
+
67
+ ### Axis-Aligned Bounding Boxes
68
+
69
+ ```python
70
+ import numpy as np
71
+ from fastbbox import (bbox_overlaps, generalized_iou, distance_iou,
72
+ complete_iou, efficient_iou, normalized_wasserstein_distance)
73
+
74
+ # Bounding boxes in [x1, y1, x2, y2] format
75
+ boxes = np.array([
76
+ [0, 0, 10, 10],
77
+ [5, 5, 15, 15],
78
+ [20, 20, 30, 30]
79
+ ], dtype=np.float32)
80
+
81
+ query_boxes = np.array([
82
+ [0, 0, 10, 10],
83
+ [12, 12, 22, 22]
84
+ ], dtype=np.float32)
85
+
86
+ iou = bbox_overlaps(boxes, query_boxes)
87
+ giou = generalized_iou(boxes, query_boxes)
88
+ diou = distance_iou(boxes, query_boxes)
89
+ ciou = complete_iou(boxes, query_boxes)
90
+ eiou = efficient_iou(boxes, query_boxes)
91
+ nwd = normalized_wasserstein_distance(boxes, query_boxes)
92
+ ```
93
+
94
+ ### Oriented Bounding Boxes (OBB)
95
+
96
+ ```python
97
+ import numpy as np
98
+ import math
99
+ from fastbbox import bbox_overlaps_obb
100
+
101
+ # Oriented bounding boxes in [center_x, center_y, width, height, angle_radians] format
102
+ obb_boxes = np.array([
103
+ [0, 0, 4, 2, 0],
104
+ [1, 0, 4, 2, math.pi/4],
105
+ [0, 0, 2, 2, math.pi/6],
106
+ ], dtype=np.float32)
107
+
108
+ obb_query_boxes = np.array([
109
+ [0, 0, 4, 2, 0],
110
+ [2, 2, 2, 2, 0],
111
+ ], dtype=np.float32)
112
+
113
+ obb_iou = bbox_overlaps_obb(obb_boxes, obb_query_boxes)
114
+ ```
115
+
116
+ ## Features
117
+
118
+ ### Axis-Aligned Bounding Box IoU Variants
119
+
120
+ All variants accept boxes in `[x1, y1, x2, y2]` top-left-bottom-right format:
121
+
122
+ - **Standard IoU**: Classic Intersection over Union
123
+ - **Generalized IoU (GIoU)**: Considers enclosing area; values in `[-1, 1]`
124
+ - Reference: [Generalized Intersection over Union](https://arxiv.org/abs/1902.09630)
125
+ - **Distance IoU (DIoU)**: Penalizes center point distance
126
+ - Reference: [Distance-IoU Loss](https://arxiv.org/abs/1911.08287)
127
+ - **Complete IoU (CIoU)**: Adds aspect ratio consistency penalty to DIoU
128
+ - Reference: [Distance-IoU Loss](https://arxiv.org/abs/1911.08287)
129
+ - **Efficient IoU (EIoU)**: Separate width/height penalties for faster convergence
130
+ - Reference: [Focal and Efficient IOU Loss](https://arxiv.org/abs/2101.08158)
131
+ - **Normalized Wasserstein Distance (NWD)**: Optimal transport-based similarity, values in `[0, 1]`
132
+ - Effective for tiny object detection
133
+ - Reference: [Normalized Gaussian Wasserstein Distance](https://arxiv.org/abs/2110.13389)
134
+
135
+ ### Oriented Bounding Box (OBB) IoU
136
+
137
+ Accepts boxes in `[center_x, center_y, width, height, angle_radians]` format:
138
+
139
+ - Exact calculation for axis-aligned boxes (angle = 0)
140
+ - Approximation-based calculation for rotated boxes using AABB intersection with angle-based scaling
141
+ - Batch processing support
142
+
143
+ ## Performance
144
+
145
+ FastBBox provides significant speedup over pure Python implementations, especially for large numbers of bounding boxes.
146
+
147
+ Run `python benchmark_fastbbox.py` to benchmark on your system.
148
+
149
+ ### When to Use Each Variant
150
+
151
+ - **IoU**: Standard evaluation, NMS (Non-Maximum Suppression)
152
+ - **GIoU**: Training loss for non-overlapping boxes
153
+ - **DIoU**: Object detection training where center distance matters
154
+ - **CIoU**: Bounding box regression with aspect ratio consistency
155
+ - **EIoU**: Fast convergence with separate width/height penalties
156
+ - **NWD**: Tiny object detection
157
+ - **OBB IoU**: Rotated object detection, text detection, aerial imagery
158
+
159
+ ## OBB Implementation Details
160
+
161
+ The OBB IoU implementation uses different strategies based on box orientations:
162
+
163
+ 1. **Axis-Aligned Boxes** (angle = 0): Exact intersection calculation
164
+ 2. **Rotated Boxes**: AABB intersection with scaling factor `cos(|angle1|) * cos(|angle2|)`, minimum 50% retention
165
+
166
+ For exact rotated box IoU, consider implementing Sutherland-Hodgman clipping or the Separating Axes Theorem (SAT).
167
+
168
+ ## Development
169
+
170
+ ### Building Locally
171
+
172
+ ```bash
173
+ pip install build scikit-build-core cmake nanobind
174
+ python -m build
175
+ ```
176
+
177
+ ### Testing Your Build
178
+
179
+ ```bash
180
+ # Correctness tests (compares fastbbox against Python reference implementations)
181
+ python test_fastbbox.py # Summary output
182
+ python test_fastbbox.py --verbose # Detailed output with values
183
+ python test_fastbbox.py -f iou giou # Test specific functions
184
+
185
+ # Performance benchmarks
186
+ python benchmark_fastbbox.py # Summary output
187
+ python benchmark_fastbbox.py --verbose # Detailed timing per run
188
+ python benchmark_fastbbox.py --size 1000 # Test with 1000 boxes
189
+ python benchmark_fastbbox.py --runs 10 # 10 iterations
190
+ ```
191
+
192
+ #### Test File Options
193
+
194
+ **test_fastbbox.py** - Correctness validation:
195
+ - `--verbose, -v`: Show detailed output with expected/actual values
196
+ - `--function, -f`: Test specific functions (iou, giou, diou, ciou, eiou, nwd, obb)
197
+ - `--tolerance, -t`: Tolerance threshold (default: 1e-5)
198
+ - `--obb-tolerance`: OBB-specific tolerance (default: 1e-3)
199
+ - `--size, -s`: Number of test boxes (default: 100)
200
+
201
+ **benchmark_fastbbox.py** - Performance benchmarks:
202
+ - `--verbose, -v`: Show individual run times and statistics
203
+ - `--function, -f`: Benchmark specific functions
204
+ - `--size, -s`: Number of boxes (default: 500)
205
+ - `--runs, -r`: Number of iterations (default: 5)
206
+
207
+ ## Requirements
208
+
209
+ - Python 3.9+
210
+ - NumPy >= 1.19.0
211
+
212
+ ## License
213
+
214
+ MIT License - see LICENSE file for details.