- Replace execute_process(tar) with file(ARCHIVE_EXTRACT) for native .zip support
and better Windows path handling when CMAKE_VERSION >= 3.18
- Replace execute_process copy with file(COPY) and existence check for reliable
CMakeLists.txt copying to avoid timing/path issues on Windows
- Maintains backward compatibility with older CMake versions and Linux behavior
Fixes issue #28608
imgproc: fix minEnclosingCircle O(n^3) worst case by adding Welzl shuffle #28548
Welzl's algorithm requires random permutation of input points to
achieve expected O(n) time. Without shuffling, sorted inputs such
as those produced by findContours() trigger O(n^3) worst case.
Fix: copy input to std::vector<PT> and apply cv::randShuffle()
before processing. Uses OpenCV's RNG so cv::setRNGSeed() ensures
reproducible behavior.
Original benchmark (5088 contour points, Release, AVX2):
findContours output: 3.93 ms → 0.033 ms (119x speedup)
Random points: 0.051 ms → 0.049 ms (no regression)
Perf test results (this PR, Release, AVX2):
| Input | N | Time |
|-------|---|------|
| Sequential circle points | 10000 | 0.03 ms |
| Sequential circle points | 5000 | 0.01 ms |
| Random points (CV_32F) | 100000 | 1.87 ms |
| Random points (CV_32S) | 100000 | 2.81 ms |
Fixes#28546
### 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
Identify ArUco markers based on threshold to reduce false positives #28289
**Goal:** parametrize the current marker identification process (pixel-based majority count) to reduce the number of false positives while maintaining high recall. Useful in high risk scenarios in which false positives are not acceptable.
**Context:** This PR builds on top of https://github.com/opencv/opencv/pull/23190 in which we've introduced a pixel-based confidence in the marker detection.
**Solution:** Include a new parameter: `validBitIdThreshold` used to identify markers based on the pixel count of each cell. Set the parameter default either to 50% which is equivalent to the current majority count implementation or to 49% which already singnificantly reduces the number of false positives (see details below).
**Test coverage:**
- Unit tests: `CV_ArucoDetectionThreshold`, `CV_InvertedArucoDetectionThreshold`
- The impact of `validBitIdThreshold` on false positives was also tested using the benchmark dataset: `MIRFLICKR-25k` https://www.kaggle.com/datasets/skfrost19/mirflickr25k which contains random images without any markers. Every marker detection is a false positive.
Example of images in the dataset:


**Results:** A threshold of 49% already allows to significantly reduce the number of false positives for the dict `DICT_4X4_1000`:
- `5942` false positives for `validBitIdThreshold = 0.5`
- `629` false positives for `validBitIdThreshold = 0.49` and `0.46`
- number of false positives divided by `9.5` when compared to `validBitIdThreshold = 0.5`
- `139` false positives for `validBitIdThreshold = 0.43` and `0.4`
- number of false positives divided by `42` when compared to `validBitIdThreshold = 0.5`
Dicts with a higher number of cells are not as impacted since it's much harder to obtain false positives. However, the less cells in a marker the further away it can be reliably detected, so the dict `DICT_4X4_1000` is commonly used.
<img width="1280" height="800" alt="false_positive_image_rate" src="https://github.com/user-attachments/assets/1a0ee16a-221d-443e-835b-022ed6dea6b0" />
In the image attached, the values of `validBitIdThreshold` tested are: `0.10f, 0.20f, 0.30f, 0.40f, 0.43f, 0.46f, 0.49f, 0.50f, 0.53f, 0.56f, 0.60f, 0.70f, 0.80f, 0.90f`
Summary of the results: [summary.csv](https://github.com/user-attachments/files/24315662/summary.csv)
Note that we can also analyse the number of false positives per marker `id`. For example, here's the histogram for the dict `DICT_4X4_1000`. (The CSV attached contains all the results)
<img width="1440" height="640" alt="false_positive_ids_DICT_4X4_1000_thr0 50" src="https://github.com/user-attachments/assets/af4f3ff8-9b8f-4682-9d51-a090c2610d8c" />
For example, the marker id 17 is detected 252 times with `validBitIdThreshold = 0.5` and only 34 times with `validBitIdThreshold = 0.49`. Looking at marker 17 (see below), we understand that this simple pattern randomly occurs in images.
<img width="447" height="441" alt="Marker17" src="https://github.com/user-attachments/assets/f5d09227-b39b-4598-94f9-b529f8300703" />
Results for every dict and every `validBitIdThreshold` [per_id.csv](https://github.com/user-attachments/files/24315667/per_id.csv)
**Missing coverage:** there is no labeled dataset with images containing markers to analyse the impact of on the recall (i.e. look at the true positive rate). For my specific use case (drones) any threshold above `0.4` allows to maintain a high recall in all conditions.
### 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
- [ ] The PR is proposed to the proper branch
- [ ] 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
DNN: Fix OpenVINO 2026 build failure due to ov::Tensor::data() const change #28592
Fixes: https://github.com/opencv/opencv/issues/28586
### 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
### PR Description
OpenVINO 2026 changed ov::Tensor::data() to return `const void*`
instead of `void*`. This causes a build error in
modules/dnn/src/op_inf_engine.cpp when constructing a cv::Mat
wrapper over Tensor memory.
Tensor memory for input/output blobs remains mutable, but the API
now enforces const-correct access. This patch casts away const with
an explicit comment to preserve existing zero-copy semantics and
restore compatibility with OpenVINO 2026.
Preserves existing zero-copy semantics of the OpenVINO backend without altering runtime behavior.
Tested by building OpenCV 4.x against OpenVINO 2026.0.0 on Ubuntu 24.04.
In fitEllipseDirect, `double det = fabs(cv::determinant(M))` applies
fabs() unnecessarily since the next line `if (fabs(det) > 1.0e-10)`
already takes the absolute value. Remove the outer fabs() to avoid
the redundant operation.
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
imgcodecs(webp): improve IMWRITE_WEBP_LOSSLESS_MODE to support exact lossless compression #28519Close#28503
Add IMWRITE_WEBP_LOSSLESS_MODE enum to control lossless strategy:
- IMWRITE_WEBP_LOSSLESS_OFF: Lossy compression.
- IMWRITE_WEBP_LOSSLESS_ON: Optimize/drop color in transparent pixels.
- IMWRITE_WEBP_LOSSLESS_PRESERVE_COLOR: Preserve color in transparent pixels.
Note: Currently limited to still images; animated WebP support is deferred per YAGNI.
### 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 IPP warpAffine #28562
The issue is that we compute the inverse transformation and pass that to the HAL, but tell IPP that we use the actual transformation.
https://github.com/opencv/opencv/blob/a269a489b94b84717691533a04f79d9a0e5f479a/modules/imgproc/src/imgwarp.cpp#L2399-L2412
I have added an additional test with `CV_16S` Mats to test the IPP implementation, because right now no other `warpAffine` test enters the IPP branch.
This fixes#28554.
### 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
This commit addresses a compiler warning encountered when building with GCC 13 and C++20.
The compiler triggers a false-positive -Wstringop-overflow warning in `findKSides`.
By adding `sides.reserve(k)`, we explicitly inform the compiler about the required
memory allocation, which suppresses the warning and provides a minor optimization
by avoiding potential reallocations.
DNN: Fix Squeeze to remove all size-1 dims when axes is empty #28425Fixes#28424
OpenCV Extra: [opencv/opencv_extra#1308](https://github.com/opencv/opencv_extra/pull/1308)
This PR fixes the ONNX Squeeze operator to correctly remove all size-1 dimensions when `axes` is not provided, conforming to the ONNX specification.
### Details
Per [ONNX Squeeze specification](https://onnx.ai/onnx/operators/onnx__Squeeze.html):
> 'If axes is not provided, all the single dimensions will be removed from the shape.'
Previously, OpenCV DNN would not remove any dimensions in this case, causing shape mismatch errors with models like LaMa (inpainting).
### Example
```python
# Input: [1, 1, 2, 4]
# Squeeze with no axes attribute
# Before: [1, 1, 2, 4] ✗ (No change)
# After: [2, 4] ✓ (matches ONNX Runtime)
```
### Tests
Added `testONNXModels("squeeze_no_axes")` which validates this behavior with new test data.
opencv_extra_pr=opencv/opencv_extra#1324
### 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 (4.x for bug fixes)
- [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
docs(calib3d): clarify coordinate systems in projectPoints, undistort Points, and fisheye::undistortPoints #28333
This PR improves documentation clarity by explicitly describing:
- Input/output coordinate systems (pixel vs normalized coordinates)
- When to use normalized vs pixel coordinates in undistortPoints output
- Differences between fisheye and standard pinhole camera models
- Coordinate system transformations for better understanding
Changes:
- projectPoints: Added explicit note about input (world coords) and output (pixel coords)
- undistortPoints: Clarified that input is pixel coordinates, and output depends on parameter P (normalized vs pixel)
- fisheye::undistortPoints: Added comprehensive documentation including coordinate systems, when to use fisheye vs standard model, and distortion coefficient differences
These improvements help users avoid ambiguity when using these functions for camera calibration and 3D vision pipelines.
features2d: add missing KAZE DIFF_CHARBONNIER support #28324
### Description
This PR fixes the missing implementation for `DIFF_CHARBONNIER` diffusivity type in KAZE feature detector.
### Changes
- Added `charbonnier_diffusivity()` call for `DIFF_CHARBONNIER` type in `Create_Nonlinear_Scale_Space()`
- Added proper error handling for unsupported diffusivity types
### Problem
When using KAZE with `DIFF_CHARBONNIER` diffusivity type, keypoint coordinates were not computed at subpixel level, because the code lacked the specific handling for this diffusivity mode.
### Solution
The `charbonnier_diffusivity()` function already exists in `nldiffusion_functions.cpp`, it just wasn't being called. This PR adds the missing `else if` branch to call it, matching the pattern already implemented in `AKAZEFeatures.cpp`.
Fixes#27134
### 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 copyleft license.
- [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
- [ ] The feature is well documented and sample code can be built with the project CMake
optimize(dnn): parallelize Slice layer implementation (4.x) #28511
### Summary
Backport of PR #28447 to 4.x branch.
### Description
This PR optimizes the SliceLayer implementation for strided inputs (where step > 1). The original implementation used a recursive element-wise copy (getSliceRecursive) for any strided slice, which was extremely inefficient.
This PR introduces:
- **Parallelization**: Uses `cv::parallel_for_` to parallelize the outermost dimension of the slice operation.
- **Memcpy Optimization**: Automatically detects "pseudo-contiguous" blocks in strided slices (e.g., slicing an outer dimension but keeping inner dimensions intact) and uses `std::memcpy` instead of scalar loops.
- **Refactoring**: Replaces the recursive function with a dedicated `ParallelSlice` loop body.
### Impact
Significant performance improvement for strided slice operations (common in detection heads, strided sampling, etc.).
### Benchmark Results
Tested on CPU with 20 threads.
| Test Case | Baseline (ms) | Optimized (ms) | Speedup |
| :--- | :--- | :--- | :--- |
| Strided Axis 0 [::2, ...] | 1.10 | 0.02 | **~55x** |
| Strided Axis 2 [..., ::2] | 1.15 | 0.11 | **~10.5x** |
### 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
- [ ] The feature is well documented and sample code can be built with the project CMake
- Change 'element' to 'kernel' in LaTeX formulas to match actual parameter name
- Fix erode() and dilate() function documentation (lines 2330, 2338, 2362, 2370)
- Fix MorphTypes enum documentation (MORPH_OPEN, MORPH_CLOSE, MORPH_GRADIENT, MORPH_TOPHAT, MORPH_BLACKHAT)
- Fix backtick formatting in dilate() documentation
Resolves#18095