fix(python): handle non-native NumPy byte order 🤖🤖🤖 - #30369
Python bindings can read non-native-endian NumPy inputs as native bytes, producing incorrect values or NaN. Mark swapped arrays for the existing cast path before constructing `Mat`; this also rejects incompatible output/in-place destinations before writes.
Closes#30368. Targets 4.x so the common bridge fix can be merged into 5.x.
Validation on macOS ARM64, Python 3.11.11, NumPy 2.4.6:
- Built current 4.x and 5.x. Three regression tests cover 20 dtype/layout/output cases; 18 fail before and all pass after. Read-only inputs and rejected destinations remain unchanged.
- 21 native-input timing cells on 4.x, 101 alternating pairs: fixed/baseline median time 0.957–1.005×, identical results. The 5.x check also stayed within 0.971–1.004×.
- Draft: Linux/hosted CI validation remains pending.
### Pull Request Readiness Checklist
- [x] I agree to contribute to the project under Apache 2 License.
- [x] The patch is not based on GPL or other incompatible code.
- [x] The PR targets the appropriate branch.
- [x] The original bug report is linked.
- [x] Regression tests and native-input performance checks are included; no external test data is needed.
- [x] No public API, feature documentation or sample changes are needed.
fix(python): set module metadata on generated functions - #30135Fixes#19349.
Generated Python functions such as `cv2.GaussianBlur` expose `__module__ = None`, so `inspect.getmodule()` returns `None`.
Pass the defining module name to `PyCFunction_NewEx` during registration. The existing `PySafeObject` wrapper manages the string reference. Function definitions, call flags, `__self__` and namespace ownership stay unchanged.
The tests cover both expressions from the ticket and module lookup, native-callable classification and pickle identity for the root, `cv2.utils` and `cv2.utils.nested`. The expected ticket output is:
```text
cv2
<built-in function GaussianBlur>
```
CPython represents native extension functions as `BuiltinFunctionType`, including `math.sin`. This patch preserves that representation while supplying the missing module metadata. See the [Python C API documentation](https://docs.python.org/3.13/c-api/structures.html#c.PyCFunction_Type).
### Validation
- Compiled isolated checks using the pristine and patched `createSubmodule` and `init_submodule` code and the unchanged `PySafeObject` wrapper. Root and nested call, constant, native type, representation and pickle controls pass on both. The pristine module assertion fails with `None`; patched module metadata and `inspect.getmodule()` pass. These checks use an echo callback and validate registration, rather than an OpenCV kernel.
- The ticket regression fails with `None != 'cv2'` against the installed OpenCV 4.12.0 binary. Three existing namespace and class-alias tests and four native-function representation controls pass against that binary and Python's standard library.
- `py -3.13 -m py_compile modules/python/test/test_misc.py` and `git diff --check` pass.
I have not built the full checkout locally. The [current-head CI workflow](https://github.com/opencv/opencv/actions/runs/37276602842) is awaiting maintainer approval (`action_required`) with no jobs yet. The updated binding tests have not run in CI. On the previous head, `8600aa69`, the Python suite reported 291 tests with 18 skips and `test_function_module` passed. The new ticket regression was added afterward, so those results do not validate it. An earlier macOS x64 native stitching test aborted with exit 134 outside this patch; its maintainer-triggered rerun was queued before this update.
### Pull Request Readiness Checklist
See https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request.
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
The regressions use existing Python functions and require no external test data or performance benchmark.
- The feature-documentation and sample-build item does not apply to this metadata bug fix.
### AI assistance disclosure
AI assistance disclosure: AI-assisted development tools were used during investigation and implementation. The reported tests were run against the final diff.
python: mark documented None output arrays as optional in typing stubs 🤖🤖🤖 - #30139Fixes#30138
The generated Python stubs type several output arrays as required, although OpenCV's own Python samples and tutorials pass `None` for them and the function allocates the output. These arrays are `InputOutputArray`/`OutputArray` parameters without a C++ default, so the stub generator does not add `| None`. As a result, mypy rejects correct code with `No overload variant ... matches [call-overload]`.
This PR adds `make_optional_arg` entries to `NODES_TO_REFINE` in `modules/python/src2/typing_stubs_generation/api_refinement.py`, the same approach as #28470 (`calibrateCamera`) and #27564:
| Function | Argument |
|---|---|
| `calcOpticalFlowPyrLK` | `nextPts` |
| `calcOpticalFlowFarneback` | `flow` |
| `normalize` | `dst` |
| `kmeans` | `bestLabels` |
| `drawKeypoints` | `outImage` |
| `drawMatches` | `outImg` |
| `drawMatchesKnn` | `outImg` |
`None` is only valid at runtime when the corresponding flag is not set (`OPTFLOW_USE_INITIAL_FLOW`, `KMEANS_USE_INITIAL_LABELS`, `DrawMatchesFlags_DRAW_OVER_OUTIMG`). Like `distCoeffs` in #28470, the change only widens the accepted type and does not change bindings or runtime behaviour.
### Verification
- I ran `gen2.py` from this branch and from `4.x` (62587ae) using the CMake-generated `gen_python_config.json`. The only differences in the generated `cv2/__init__.pyi` are 16 signatures (Mat and UMat overloads for each function; `drawMatches` has two C++ overloads). In each one, the listed argument changes from `cv2.typing.MatLike` / `UMat` to `... | None`. With a fixed `PYTHONHASHSEED` no other file differs; without it, the import order in `cv2/typing/__init__.py` varies from run to run because `generation.py` iterates a set, independently of this change.
- mypy 2.4.0 (MYPYPATH pointing at the generated stubs) on the 7 calls from #30138, for example `cv2.calcOpticalFlowPyrLK(prev, curr, pts, None)` and `cv2.normalize(img, None, 0, 255, cv2.NORM_MINMAX)`: all 7 fail with `call-overload` on the base stubs, and mypy reports no errors for these calls on the patched stubs (the generated stubs have some pre-existing internal errors, unchanged by this PR). The same calls run correctly with `opencv-python-headless` 4.14.0.94 and 5.0.0.93.
- No C++ or binding code changes. No regression test is added, because the repository has no existing test for the stub generator or `api_refinement.py` to extend.
_Prepared with AI assistance (Claude Code); I reviewed the change and the verification results._
**Update:** Added a second commit: `NODES_TO_REFINE` entries whose function, class or namespace is absent from the build (e.g. `video` or `calib3d` disabled via `BUILD_LIST`) are now skipped instead of aborting stub generation, as the `dnn`/`cuda` refinements already do. This also fixes the pre-existing failure for builds without `calib3d`. A wrong argument name in a present function still raises `RuntimeError`; a misspelled function name is now skipped like an absent one. Builds without `features2d` still fail for a separate reason (the `Feature2D` aliases in `predefined_types.py`), which I'll address in a follow-up.
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
🤖 Generated with [Claude Code](https://claude.com/claude-code)
SequenceTypeNode and ClassTypeNode always format as _typing.Sequence[...]
and _typing.Type[...], but ContainerTypeNode only reports the typing
import as required when compatible_to_runtime_usage is set. Stubs for
modules that use these nodes without any other _typing usage (e.g.
cv2/videoio_registry) reference _typing without importing it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Backport of #29905 to the 4.x branch, applied verbatim: after this change
`modules/python/package/cv2/__init__.py` is byte-identical to the 5.x version
(same blob 99685b3791), since both branches carried the same code here.
`import cv2` unconditionally rewrites the environment; when LD_LIBRARY_PATH
was previously unset this creates a dangling separator, i.e. an empty entry
which, per ld.so(8), resolves to the current working directory of every
subsequently spawned child process. Children may then pick up same-named
shared libraries from the CWD and fail (real-world case reported in
opencv/opencv-python#1268: a Nuitka-standalone app's `xdg-open -> kde-open`
dying with `libssl.so.3: version 'OPENSSL_3.2.0' not found`; reproduced on
4.11.0.86 - 4.14.0.94 manylinux wheels). The Windows PATH line has the same
dangling-separator pattern.
Identical to #29905: factor the prepend into _prepend_env_paths(), filter
empty entries, write the variable only when there is something to add, and
join with the old value without producing an empty entry.
The follow-up question of not mutating the process environment at all
remains tracked in #28994.
Fixing python wrapper around ECCParameters to include itersPerLevel #29148
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
python: fix segfault on 0-channel numpy array input #28747
### Pull Request Readiness Checklist
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
N/A: a Python unit test is added in `modules/python/test/test_mat.py`. No external test data required.
- [x] The feature is well documented and sample code can be built with the project CMake
N/A: this is a bug fix, not a new feature. No documentation update needed.
### Problem
Passing a numpy array with shape `(H, W, 0)` (0 channels) to any OpenCV function that accepts a `Mat` argument (e.g. `cv2.resize`, `cv2.warpAffine`, `cv2.blur`) causes a **segfault**.
**Reproducer:**
```python
import cv2
import numpy as np
arr = np.zeros((100, 100, 0), np.uint8)
cv2.resize(arr, (200, 200)) # segfault
```
### Root Cause
In `modules/python/src2/cv2_convert.cpp`, the numpy→Mat conversion checks channel validity only against `CV_CN_MAX` (upper bound):
```cpp
if (channels > CV_CN_MAX) // channels=0 passes this check
```
With `channels=0`, `CV_MAKETYPE(0, 0)` produces `type=-8`, which corrupts the Mat's internal type field and causes undefined behavior downstream.
### Fix
Extend the check to also reject `channels < 1`:
```cpp
if (channels < 1 || channels > CV_CN_MAX)
```
**After fix:**
```
cv2.error: src unable to wrap channels, invalid count (0, must be in [1, 512])
```
### Notes
- This affects all functions that accept a `Mat` input, not just `cv2.resize`
- The same bug exists in the `5.x` branch
- A 0-channel array has no valid OpenCV Mat representation; rejecting it with a clear error is the correct behavior and poses no backward-compatibility risk (the previous behavior was a crash)
When a module is disabled in an incremental build (e.g. switching from
-DBUILD_opencv_gapi=ON to OFF), its typing stub directory persists from
the previous build. The stubs generator only creates directories for
enabled modules but never removes old ones, and the copy step merges
rather than replaces, so stale .pyi files propagate to both the loader
directory and the install prefix.
This causes type-checkers (mypy, pyright) to report errors for stubs
that reference symbols from modules that are no longer available.
Fix both propagation paths:
- generation.py: remove all subdirectories under the stubs output root
before regenerating, so only currently enabled module stubs exist in
the build directory. Top-level files (py.typed) are preserved.
- copy_typings_stubs_on_success.py: remove stale .pyi files and
py.typed markers from the loader directory before copying fresh stubs,
so leftover stubs from a previous copy are cleaned up. Runtime .py
files are not affected.
Fix two issues that cause `import cv2` to fail when building with
-DBUILD_opencv_gapi=OFF:
1. In `has_all_required_modules()`, the function parameter `type_node`
was ignored in favor of the enclosing scope's loop variable `node`.
This works by accident when called as `has_all_required_modules(node)`
but is incorrect — the parameter should be used directly.
2. In `__load_extra_py_code_for_module()`, only `ImportError` was
caught. When a stale gapi submodule directory exists from a previous
build, gapi/__init__.py raises `AttributeError` (not `ImportError`)
because it tries to access C++ bindings that don't exist. Now catches
both exception types for defense-in-depth.
Refs: #26098
imgproc: fix HoughCircles Python return type to allow None #28621
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
### Description
Fixes https://github.com/opencv/opencv/issues/28528
`HoughCircles` returns `None` when no circles are found, but the auto-generated Python type stub declares the return type as `MatLike` without `None`. This causes type checkers (mypy/pyright) to miss potential `None` dereferences.
**Fix:** Add `HoughCircles` to `NODES_TO_REFINE` in `api_refinement.py` using the existing `make_optional_none_return` helper - the same pattern already used for `imread` and `imdecode`.
This contribution was developed with AI assistance (Claude Code).
Fix inRange type signature to accept Scalar values #28536Fixes#28534
The Python type signature for cv2.inRange was too restrictive, requiring MatLike for lowerb and upperb parameters. However, the C++ implementation accepts InputArray which includes Scalar values (tuples, floats, etc.).
This caused type checkers to incorrectly flag valid code from official tutorials as type errors.
Added make_matlike_or_scalar_arg() refinement function to create union types MatLike | Scalar for affected parameters, matching the C++ InputArray behavior.
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
Fix memory leak in pyopencv_to for path-like objects #28047
This PR fixes a memory leak in pyopencv_to when handling path-like objects (e.g., pathlib.Path).
Problem:
PyOS_FSPath() returns a new strong reference, but the code was not calling Py_XDECREF to decrement it, causing a memory leak on every call with path-like arguments.
Solution:
Store the returned reference from PyOS_FSPath() in a separate variable path_obj
Call Py_XDECREF(path_obj) on all function exit paths (both success and error paths)
This ensures proper reference counting without changing the function's behavior
Testing:
The leak can be reproduced using the steps in issue #28046 with Python built with --with-address-sanitizer. This fix ensures the reference is properly released.
Fixes#28046
Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
✓ I agree to contribute to the project under Apache 2 License.
✓ To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
✓ The PR is proposed to the proper branch (4.x)
✓ There is a reference to the original bug report and related work (#28046)
NA There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
✓ The feature is well documented and sample code can be built with the project CMake
Correct minAreaRect angle to be in range [-90, 0) #28051
### Pull Request Readiness Checklist
Box angle range over all imgproc tests is in interval `[-90, -0.0581199]`
resolves https://github.com/opencv/opencv/issues/27667
resolves https://github.com/opencv/opencv/issues/19472
resolves https://github.com/opencv/opencv/issues/24436
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
Fix Python Scalar typing issue #27528#27620
- Add ScalarInput and ScalarOutput types for better type safety
- ScalarInput: Union[Sequence[float], float] for function parameters
- ScalarOutput: Sequence[float] for function return values
- Keep original Scalar type for backwards compatibility (deprecated)
- Add refinement functions to apply new types to specific functions
- Functions returning scalars now use ScalarOutput (mean, sumElems, trace)
- Drawing functions now use ScalarInput for color parameters
- Resolves MyPy compatibility issues with scalar return values
- Maintains full backwards compatibility
closes#27528
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x ] The PR is proposed to the proper branch
- [x ] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x ] The feature is well documented and sample code can be built with the project CMake
### Pull Request Readiness Checklist
resolves#16295
```
docker run --gpus 0 -v ~/opencv:/opencv -v ~/opencv_contrib:/opencv_contrib -it nvidia/cuda:12.8.1-cudnn-devel-ubuntu22.04
apt-get update && apt-get install -y cmake python3-dev python3-pip python3-venv &&
python3 -m venv .venv &&
source .venv/bin/activate &&
pip install -U pip &&
pip install -U numpy &&
pip install torch --index-url https://download.pytorch.org/whl/cu128 &&
cmake \
-DWITH_OPENCL=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_DOCS=OFF \
-DWITH_CUDA=ON \
-DOPENCV_DNN_CUDA=ON \
-DOPENCV_EXTRA_MODULES_PATH=/opencv_contrib/modules \
-DBUILD_LIST=ts,cudev,python3 \
-S /opencv -B /opencv_build &&
cmake --build /opencv_build -j16
export PYTHONPATH=/opencv_build/lib/python3/:$PYTHONPATH
```
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
Extend image I/O API with metadata support #27499
Covered with the PR:
* AVIF encoder can write exif, xmp, icc
* AVIF decoder can read exif
* JPEG encoder can write exif
* JPEG decoder can read exif
* PNG encoder can write exif
* PNG decoder can read exif
This PR is a sort of preamble for #27488. I suggest to merge this one first to OpenCV 4.x, then promote this change to OpenCV 5.x and then provide extra API to read and write metadata in 5.x (or maybe 4.x) in a style similar to #27488. Maybe in that PR exif packing/unpacking should be done using a separate external API. That is, metadata reading and writing can/should be done in 2 steps:
* [1] pack and then [2] embed exif into image at the encoding stage.
* [1] extract and then [2] unpack exif at the decoding stage.
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
Consider QRCode ECI encoding #24426
### Pull Request Readiness Checklist
related: https://github.com/opencv/opencv/pull/24350#pullrequestreview-1661658421
1. Add `getEncoding` method to obtain ECI number
2. Add `detectAndDecodeBytes`, `decodeBytes`, `decodeBytesMulti`, `detectAndDecodeBytesMulti` methods in Python (return `bytes`) and Java (return `byte[]`)
3. Allow Python bytes to std::string conversion in general and add `encode(byte[] encoded_info, Mat qrcode)` in Java
Python example with Kanji encoding:
```python
img = cv.imread("test.png")
detect = cv.QRCodeDetector()
data, points, straight_qrcode = detect.detectAndDecodeBytes(img)
print(data)
print(detect.getEncoding(), cv.QRCodeEncoder_ECI_SHIFT_JIS)
print(data.decode("shift-jis"))
```
```
b'\x82\xb1\x82\xf1\x82\xc9\x82\xbf\x82\xcd\x90\xa2\x8aE'
20 20
こんにちは世界
```
source: https://github.com/opencv/opencv/blob/ba4d6c859d21536f84e0328c16f4cc3e96bf3065/modules/objdetect/test/test_qrcode_encode.cpp#L332

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
Add HoughCirclesWithAccumulator binding #27389
### Pull Request Readiness Checklist
Fix#27377
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
Java VideoCapture buffered stream constructor #27284
### Pull Request Readiness Checklist
resolves#26809
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake