core: fix RVV widening load lane count (#29907) - #29921
# core: fix RVV widening load lane count
Partially fixes#29907.
The RVV `v_load_expand` implementation used the source vector lane count for the widening load. For widening loads, the number of loaded elements must match the destination widened vector lane count instead.
This change:
* uses `VTraits<_Tpwvec>::vlanes()` for the RVV widening load and conversion;
* adds regression coverage for `texpr` `select()` with byte masks across multiple data types, channel counts, mask types, strided matrices, and in-place output.
### Pull Request Readiness Checklist
See details at the OpenCV contribution guidelines.
* [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 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 an accuracy/regression test where applicable.
* [x] The change does not require documentation or sample updates.
core: handle zero-sized broadcast dimensions - #29911
### 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
Port the fix from #29878 to the 5.x branch.
This adds a guard for zero-sized destination matrices in
cv::broadcast() and a regression test covering broadcasting
from {1, 0} to {3, 0}.
The relevant BroadcastTo.* tests pass locally.
Related: #29878
ptcloud , photo test suit cleanup - #29742
## Test suite cleanup
### Given real assertions
- **ptcloud** — `HugeSceneGrowthTest`: zero assertions, including a `// Reset check` comment followed by no check.
- **ptcloud** — `PointCloud.SaveBadExtension`: passed an empty vertex set, so it exited at the empty-input guard and never reached the extension code it is named for.
- **ptcloud** — new `PointCloud.SaveEmptyVertices`: covers the early-return branch the above was hitting by accident.
### Moved
- **photo** — `Photo_Denoising.speed` → `perf/perf_denoising.cpp`: a `getTickCount` + `printf` stopwatch in the accuracy suite, asserting nothing, costing 393 ms per run.
### Library fixes found while doing the above
- **ptcloud** — `findPlanes` now converts 3-channel input instead of reshaping it: `Mat_<Vec4f>::operator=` reshapes when depths match, so a 320×240 `CV_32FC3` input silently became 240×240.
- **ptcloud** — new `RGBD_Plane.regression_3channel_matches_4channel`: nothing covered the documented 3-channel path, since all 40 `RgbdPlaneGenerate` cases feed `CV_32FC4`.
### 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
Joining BINARIES_PATHS with an unconditional trailing separator
creates an empty search-path entry when the variable was unset.
On POSIX that empty entry is CWD (ld.so), so children can load
the wrong libraries. Keep prepending extras, but only insert the
separator when an old value exists. Same join on Windows PATH.
core: fix addWeighted null kernel crash for f64 dtype and bool inputs - #29883Fixes#29880.
`cv::addWeighted` segfaults for `CV_8U`, `CV_8S`, `CV_16U`, `CV_16S`, `CV_16F`, `CV_16BF` and `CV_32F` inputs with `dtype=CV_64F`, and for `CV_Bool` inputs with any dtype. When no direct `T -> rdepth` kernel exists, `TExpr::emitBinary()` picks a wide work type and looks the kernel up again, but for those input types only `T -> T` and `T -> f32` kernels are generated, so the second lookup returns a null function pointer too. The `addInsn()` overload that takes an already resolved kernel stores it without checking, and `runInsn()` then calls through the null pointer.
Cast the operands to the work type when there is no kernel for them either, so the f64 (or f32) kernel runs on widened inputs. That is also what 4.x did, it converted the sources to the working type before computing, so an f64 destination keeps full precision instead of going through an f32 intermediate. Added the `CV_Assert` on the resolved kernel that the other emit paths already carry.
### 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 (`5.x`, the element-wise engine this regressed in does not exist on `4.x`)
- [x] There is a reference to the original bug report and related work (#29880, regressed by #29426)
- [x] There is an accuracy test (`Core_Arithm.addWeighted_dtype_29880`, which segfaults without the fix); not applicable: performance test and opencv_extra test data
- [x] N/A: this is a bug fix, no new public API or documentation needed
Fix Windows ARM64 multithreading and ASM detection - #29833
### PR Changes:
This PR lets Windows ARM64 CI run on OpenCV's default PPL backend — no `-DWITH_OPENMP=ON` and no `-DCMAKE_ASM_COMPILER` workaround needed.
**`modules/core/src/parallel.cpp`** — PPL's default `auto_partitioner` silently drops whole contiguous chunks of a `parallel_for` range on ARM64, so that work never runs (open MSVC defect [1027444](https://developercommunity.visualstudio.com/t/1027444)). Pass `static_partitioner` on ARM64, which has no range-stealing path. x86 unchanged.
**`CMakeLists.txt`** — `check_language(ASM)` picks up the runner's MinGW `cc.exe`, which sets `MINGW` and emits GNU link flags that `link.exe` silently drops, breaking the DirectX samples under `BUILD_EXAMPLES=ON`. Only accept an assembler from the MSVC toolchain.
### 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
imgproc: fix OpenCL matchTemplate TM_CCOEFF_NORMED precision loss - #29856
### Problem
`cv::matchTemplate(..., TM_CCOEFF_NORMED)` on `UMat` (OpenCL) input can return exactly `-1.0`/`1.0` for windows that are not actually near-perfect (anti-)matches, while the CPU path on the same data returns a sensible, correctly-bounded coefficient. See #21788: on the reporter's images, the CPU path gives `-0.8367...` where the OpenCL path gives exactly `-1.0` at a *different* location, so `minMaxLoc` picks the wrong match entirely.
### Root cause
The per-window denominator in `TM_CCOEFF_NORMED` is a variance-like quantity computed as a difference of two comparable-magnitude sums pulled from the image's integral images (`sum(x^2) - mean^2 * N`) -- classic catastrophic-cancellation territory. The CPU implementation (`common_matchTemplate` in `templmatch.cpp`) always accumulates these sums in `double` regardless of the input image's depth, so this is a non-issue there.
The OpenCL kernel (`matchTemplate_CCOEFF_NORMED` in `match_template.cl`), however, is fed integral images hard-coded to `CV_32F` (`integral(_image, image_sums, image_sqsums, CV_32F, CV_32F)`). On a realistic-sized image, the rounding error from that single-precision subtraction can dwarf a genuinely small-but-nonzero window variance. The corrupted (and effectively noise-dominated) ratio then spuriously trips the kernel's own `+-1` safety clamp (`normAcc()`, meant only for genuinely degenerate/near-constant windows) for windows that are not degenerate at all.
I initially assumed the fix was a missing epsilon guard (the CPU path has one: `diff2 <= min(0.5, 10*FLT_EPSILON*wndSum2) -> denominator = 0`, which the kernel lacks entirely). I verified this hypothesis against real integral-image data from an actual build and it's **false** -- adding the same epsilon guard to the float32 kernel path made *zero* difference (identical spurious-clamp count, tested on 480x640 and 1080x1920 synthetic images). The true variance in the failing windows isn't near-zero; it's just small relative to the accumulated sum magnitude, which is exactly what makes the cancellation error dominate without ever being "obviously degenerate" by the guard's own threshold. Precision is the only lever that actually fixes it.
### Fix
- Use `CV_64F` integral images (matching the CPU path exactly) when the OpenCL device supports double precision (`ocl::Device::getDefault().doubleFPConfig() > 0`), gated the same way the rest of the codebase gates double-precision OpenCL kernels (e.g. `sumpixels.dispatch.cpp`'s own `ocl_integral`, `thresh.cpp`). Verified against real integral-image data pulled from this build: residual error drops from up to `1.13` (!) to `~5e-5` (pure float32 output-storage rounding, since the result `Mat` stays `CV_32F` either way), and the spurious `+-1` clamp count drops from thousands to exactly zero, across multiple image sizes.
- On devices without double support, `matchTemplate_CCOEFF_NORMED` now returns `false` instead of silently running an already-known-inaccurate float32 kernel; `matchTemplate()`'s `CV_OCL_RUN` macro then falls through to the CPU path, which is always correct. This is a correctness-over-acceleration trade-off for this specific normalized method on such devices -- verified this fallback is exact (not just close): `cv::norm(cpuResult, gpuResult, NORM_INF) == 0.0` across three image sizes on such a device.
- Added the standard `cl_khr_fp64`/`cl_amd_fp64` extension-pragma block to `match_template.cl`, copied from the existing, already-shipping `integral_sum.cl` (same idiom used everywhere else in the codebase for this).
### Testing
- New regression test (`ccoeff_normed_large_low_contrast_image` in `modules/imgproc/test/ocl/test_match_template.cpp`) using a large (1920x1080), low-contrast synthetic image. The existing parameterized `OCL_ImageProc/MatchTemplate` test only covers small (<=100x100) images of uniformly random full-range noise, which never accumulates enough integral-sum magnitude to trigger this, so it doesn't catch the bug -- confirmed by temporarily reverting the fix and rerunning: the new test fails with `CPU minVal=-0.159..., GPU minVal=-1` (the exact reported symptom), and passes clean with the fix restored.
- Full existing `OCL_ImageProc/MatchTemplate.*` suite (96 tests, all methods/depths/channels/mask combinations) passes unchanged.
- Full existing `*MatchTemplate*` suite in `opencv_test_imgproc` (286 tests total including the new one) passes.
- Ran the full `opencv_test_imgproc` binary; the only failures (360, e.g. `StackBlur`, `HoughCircles`, `ColorBayer`) are pre-existing "can't find required data file" failures from a missing local `opencv_extra` checkout in my environment, unrelated to this change and confirmed to touch none of `templmatch.cpp`/`match_template.cl`.
Fixes#21788.
### 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
- [x] The feature is well documented and sample code can be built with the project CMake
dnn: use the full vector width in blocked-layout pointwise kernels - #29836
Four block-layout kernels share one defect: they vectorize *across the channel block*, so they only use the vector unit while it happens to match `C0`. This PR fixes all four behind one shared helper, and along the way fixes an unrelated correctness bug found in the same function.
## 1. FP16 BatchNorm writes no output
`batch_norm2_layer.cpp`, the `CV_16F` arm of the accelerated block-layout path, wraps its whole body in a condition that cannot be true:
```cpp
} else if (type == CV_16F) {
const hfloat* inptr = ...;
if (type == CV_32F) { // false by construction
```
There is no `else`, so every vector loop in that arm is dead and **nothing is written to the output**. A half-precision BatchNorm on a blocked tensor with `C0` equal to 1, 2 or 4 times the vector width returns whatever the destination buffer already held. The `CV_32F` and `CV_16BF` arms are correct; only the redundant wrapper is removed.
Confirmed with a sentinel-prefilled destination: before the fix the sentinel survives the call (`maxerr = 12346`) for all three `C0` values, after it the output is exact.
## 2. The kernels only use min(C0, VEC_SZ) lanes
`C0` is the block-layout channel block, fixed at 8 (`net_impl.hpp`, `DEFAULT_C0`), so these guards decide how much of the register gets used:
| kernel | guard | consequence with C0=8 |
|---|---|---|
| ChannelsPReLU | `C0 == VEC_SZ` | scalar at 4 lanes **and** at 16/32 |
| BatchNorm | `C0 == vlanes*{4,2,1}` | scalar at 16/32 |
| InstanceNorm | `c0 <= validC0 - VEC_SZ` | scalar at 16/32 |
| GroupNorm | `c0 <= c0_hi - VEC_SZ` | scalar at 16/32 |
PReLU is the worst case: an equality can only hold on an 8-lane build, so a default x86 SSE build (4 lanes) runs it scalar too. The other three use chunk loops that work at <= 8 lanes and fail above.
These files are not in the CPU-dispatch list, so `v_float32` is whatever `CPU_BASELINE` gives -- this is not RISC-V-specific.
### Approach
A block-layout plane is contiguous over `(H, W, C0)` and the coefficients repeat with period `C0`, so one register can span `vlanes/C0` pixels: replicate the coefficients across it and walk the plane flat.
All three spanning call sites now go through one helper, `cpu_kernels/blocked_pointwise.hpp::blockedSpanApply()`, parameterised by the per-element operation (`BlockedAffineOp`, `BlockedPReLUOp`). PReLU additionally gains a chunked path for `C0 > VEC_SZ`, which is what restores it on 4-lane targets. BatchNorm keeps its own unrolled loops and gains a whole-vector step plus a remainder loop. Pre-existing paths are untouched, so targets that already vectorized keep the same code.
**GroupNorm also gains a vector reduction.** Its mean/variance pass walked one channel at a time with a stride of `C0`, which no target vectorized at all, so that half speeds up everywhere rather than only on wide vectors. Both new GroupNorm paths are restricted to blocks owned entirely by one group; where a group boundary falls inside a block the old per-channel code still runs, because spanning would cross into channels another `parallel_for_` task is writing.
### Note for reviewers: the helper's `noinline` is load-bearing
`blockedSpanApply()` carries an explicit `noinline`. Inlined, GCC 15.2 on RISC-V speculates its stores into callers whose guard is false, which silently corrupted a neighbouring group's channels in `fastNormGroupBlockF32`. The symptom was exactly half the elements wrong at VLEN=1024 in the cases where a group splits a block; a runtime trace showed the guard evaluating false on every block, and inserting any call before the `if` made it disappear. Please do not remove the attribute.
## Benchmarks
SpacemiT K3, GCC 15.2, `CPU_BASELINE=RVV`, single thread, median of 11, pristine vs patched built back to back in one session. The board exposes two core types with different VLEN, so both columns are the same binary on the same machine.
Speedup, VLEN=256 / VLEN=1024:
| shape (NxC1xHxWxC0) | Ci | InstanceNorm | BatchNorm | GroupNorm |
|---|---|---|---|---|
| 1x32x56x56x8 | 256 | 1.01x / 14.38x | 0.91x / 11.62x | 1.85x / 14.56x |
| 1x16x28x28x8 | 128 | 1.01x / 16.27x | 0.98x / 3.95x | 1.91x / 16.01x |
| 1x8x112x112x8 | 64 | 1.02x / 12.76x | 1.03x / 1.37x | 1.98x / 12.86x |
| 1x16x56x56x4 | 64 | 3.01x / 12.47x | 4.49x / 6.18x | 3.01x / 11.78x |
ChannelsPReLU, measured separately the same way:
| shape | Ci | VLEN=256 | VLEN=1024 |
|---|---|---|---|
| 1x32x56x56x8 | 256 | 1.45x | 8.37x |
| 1x16x28x28x8 | 128 | 1.55x | 4.16x |
| 1x64x14x14x8 | 512 | 1.46x | 4.05x |
| 1x8x112x112x8 | 64 | 1.47x | 3.77x |
| 1x16x56x56x4 | 64 | 2.99x | 8.47x |
| 1x8x56x56x16 | 128 | 1.20x | 2.33x |
The VLEN=256 columns for InstanceNorm and BatchNorm are flat by construction -- `C0 == VEC_SZ` there, so those shapes already vectorized and the code is unchanged; the 0.91-1.03x spread is measurement noise. The rows that move at 256 are `C0=4` (block narrower than the vector), PReLU (broken at every width), and GroupNorm (reduction).
**Caveat on the BatchNorm numbers.** BatchNorm timings on this board are much less reproducible than the other three. The `1x8x112x112x8` case in particular measured anywhere from 1.4x to 6.9x across builds with byte-identical BatchNorm sources, and its pristine baseline moved by 26% between runs. The working set there is 3.06 MB, an exact multiple of 4096, and this hardware is sensitive to how source and destination alias in the cache; the numbers above are one back-to-back pair rather than a stable figure. InstanceNorm, GroupNorm and PReLU reproduced to within ~1% across every build.
## Testing
Verified against a scalar reference over 43 shape / `C0` / `Ci` / group combinations across the four layers, at VLEN 256 and 1024, at 1 and 8 threads, clean under `MALLOC_CHECK_=3`. Cases include partial trailing blocks, odd planes (7x7, 13x11) that exercise the remainder loops, `C0` from 2 to 64, and GroupNorm configurations where a group boundary falls inside a block -- those take the fallback and match bit-exactly, which is what confirms the ownership guard.
`opencv_test_dnn` was **not** run: the build used here is `BUILD_LIST=dnn`, which generates no dnn test target, and the board has no `opencv_extra` checkout. The blocked path's reachability was confirmed by inspection instead -- `ActivationLayer::getLayouts` passes the producer's layout through, and `useBlockLayout()` runs unconditionally in `finalizeGraph`, so these kernels are on the default path in real nets.
## Platform scope
Nothing here is behind a RISC-V `#ifdef`; this is universal-intrinsic code that compiles into every target.
| target (C0=8) | lanes | what changes |
|---|---|---|
| x86 SSE baseline (default) | 4 | PReLU newly vectorized; GroupNorm reduction newly vectorized |
| x86 AVX2 baseline | 8 | GroupNorm reduction; BatchNorm loop rewritten (same iterations) |
| x86 AVX-512 baseline | 16 | + all spanning paths go live |
| ARM64 NEON | 4 | as SSE baseline |
| ARMv7 NEON | 4 | `CV_SIMD_64F`=0, reduction path skipped |
| RVV 256 | 8 | PReLU, GroupNorm reduction |
| RVV >= 512 | 16/32 | everything |
Two changes reach a **default x86 build**: PReLU, which was scalar there because `C0 == VEC_SZ` cannot hold at 4 lanes, and the GroupNorm reduction, which was scalar everywhere. The latter changes GroupNorm's numerical output on those targets, since summation order differs -- measured at ~1e-7 relative here.
Measurements are RISC-V only; no x86 or ARM machine was available. The spanning branches were exercised on RVV at the same `vlanes/C0` ratios an AVX-512-baseline build would hit (2:1 and 4:1), but the x86-reachable changes above have had no x86 validation and are the part most worth checking in CI.
SIMD support for FP8 - #29832
### 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
- Skip downloading and embedding Unifont data when HAVE_HARFBUZZ is OFF
- Note: When HAVE_HARFBUZZ is OFF, Rubik and Unifont binaries will be excluded from the build.
When chtype is double (used by bicubic64fC1 .. bicubic64fC4),
std::is_same_v<double, float> evaluated to false.
As a result, buftype erroneously defaulted to int, and pixbuf was
allocated as int pixbuf[NCHANNELS][4].
That could trigger out of bound integer computations.
Extracted IPP to HAL for getRectSubPix function in 5.x - #29514
### 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
python: fix int32 output arrays on Windows by mapping 32-bit NPY_LONG - #29767
On Windows numpy spells `int32` as C `long`, so such arrays arrive as `NPY_LONG` (typenum 7) instead of `NPY_INT` (5). `numpyTypeToCvDepth()` has no case for it, so `pyopencv_to()` takes the cast-and-copy path — which is rejected for **output** arguments, even though the data is already bit-identical to `CV_32S`:
```python
cv.watershed(img, np.int32(markers))
```
```
cv2.error: (-5:Bad argument) in function 'watershed'
> Overload resolution failed:
> - Layout of the output array markers is incompatible with cv::Mat
```
Three tests fail on Windows for this reason, all on an int32 output argument (`markers`, `detectedIds`):
- `test_watershed`
- `test_aruco_detector_refine`
- `test_charuco_refine`
### 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
Added Bitcast layer & extended MatMul and DFT layers support - #29594
### 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
Rework accuracy test for legacy C-API cvApproxPoly and CV_PerimeterTest - #29547
### 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
**Details:**
This PR restores the deleted C-API `cvApproxPoly` tests (part of #24957).
I used `cv::pointPolygonTest` to make sure every original point is within the allowed `epsilon` distance to the final approximated polygon rather than calculate the distance to the corresponding line.
**Update:**
Restored `CV_PerimeterTest` *TEST(Imgproc_ContourPerimeter, accuracy)*.
Created a parameterized test for open/closed curves with int/float type shapes. I also added a simple 10x10 square test.
Support ONNX Cast/CastLike for FP8/FP4/INT4/UINT4/E8M0 dtypes - #29360
### 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
Refactoring and moving IPP functions to HAL for bilateral_filter in Imgproc - #29409
**Performance Numbers on Intel(R) Core(TM) i9-11900K:** https://docs.google.com/spreadsheets/d/1hnH2aGmc3D88HGnvM34xczQbRZUgsKsAHorcB-DpLq4/edit?usp=sharing
### 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
## dnn: extend engine-new layer dtype coverage (control flow, Range, Hardmax, MaxUnpool, CumSum/CumProd, MaxPool, Resize2, normalization, Gemm, MatMul)
ONNX permits these dtypes on these ops, but the engine-new layers refused them at graph-construction time, so :
- valid models either failed to load outright or
- a layer quietly converted to float32 instead (Resize2)
- ran but silently lost precision above float32's 24-bit mantissa.
Companion PR (test data) : [1406](https://github.com/opencv/opencv_extra/pull/1406)
### Support added, per layer
| Layer | Types added | Gate / kernel |
|---|---|---|
| If | Bool, 16U, 16S, 32U, 32S, 64U | Gate only — the condition-reading switch already handled every depth |
| Loop | Bool, 16U, 16S, 32U, 32S, 64U | Gate only — same as If |
| Scan | Bool, 16U, 16S, 32U, 32S, 64U | Gate only — Scan never inspects element values at all |
| Range | 16S | Kernel only — gate was already an unconditional passthrough |
| Hardmax | 64F | Gate only — the `double` kernel has existed since 2024, just unreachable |
| MaxUnpool | 64F | Gate + a genuine `double` instantiation of the value-scatter routine |
| CumSum | 32U, 64U | Gate + two instantiations of the existing running-sum template (wraparound on overflow) |
| CumProd | 32U, 64U | Gate + two instantiations of the existing running-product template |
| MaxPool | 8S, 8U, 64F | Kernel only (gate was already open) — new scalar kernel for the blocked values-only path **and** the separate values+indices path, which had its own float32-only assert |
| Resize2 | 32S (nearest-neighbor only) | Gate + native `int32` gather; bilinear/cubic now reject 32S explicitly instead of silently converting to `float` |
| RMSNorm | 64F | Kernel — `fast_norm.cpp` templated on `T`, genuine `double` accumulator |
| LayerNorm | 64F | Kernel — same shared `fast_norm.cpp` path |
| LayerNorm2 | 64F | Kernel — same shared `fast_norm.cpp` path |
| InstanceNorm | 64F | Kernel — existing SIMD float32 blocked path left untouched, new scalar `double` path added beside it |
| GroupNorm | 64F | Kernel — same treatment as InstanceNorm |
| Gemm | 64F | Kernel — dedicated `cv::gemm` path, bypassing the float-only fastGemm/MLAS kernels |
| MatMul | 64F, 32S, 64S, 32U, 64U | Gate + two new paths: per-batch `cv::gemm` for 64F, and a direct 64-bit-accumulated loop for the four integer types |
Removed `test_maxpool_2d_uint8` from `opencv_all_denylist` : with 8U now supported, the test passes NORMASSERT on all backend/target combinations .
### 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
This PR is about Introducing cuDNN JIT support for the DNN Module
### 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
- [ ] 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
Added GridSample BiCubic, Dropout support - #29783
Updated ONNX coverage after this PR: 74.8%
### 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
Extend data type support in elementwise, gather and scatter layers - #29786
### PR Changes:
### Support added, per layer
| Layer | Types added | Gate / kernel |
|---|---|---|
| Abs | 8U, 8S, 16U, 16S, 32U, 32S, 64U, 64S | Gate + new templated integer kernel |
| Sign | 8U, 8S, 16U, 16S, 32U, 32S, 64U, 64S | Gate + same templated kernel |
| Neg | 32S | Gate only. The kernel already had a `CV_32S` branch |
| GatherElements | 64F, 16U, 16S, 32U, 64U | Gate + element-width dispatch |
| Scatter | 64F, 16U, 16S, 32U, 64U | Gate + dispatch arms, all five reductions checked |
| ScatterND | 64F, 16U, 16S, 32U, 64U | Gate + dispatch arms, same as Scatter |
| GatherND | 64F, 16U, 16S, 32U, 64U | Gate + element-width dispatch |
| Slice2 | (fix) | Kernel. Wrong-width copy, see below |
`Abs`/`Sign` use one template over all widths with the signed/unsigned split resolved at compile time;
unsigned `abs` short-circuits to `copyTo` and unsigned `sign` reduces to `x != 0`. `GatherElements` and
`GatherND` only move elements, so their per-dtype arms collapsed to four widths. `GatherND` also unified a
target-conditional gate that split `16F`/`32F` by target in a file with no OpenCL path.
`Slice2` had two duplicated depth chains that both fell through to `run_parallel<float>`, a 4-byte copy, so
`64F`/`64U` truncated and `16U`/`16S` read and wrote past the element. Reachable only when the innermost axis
has `step != 1`, which is why the float32 slice tests passed. Now dispatches on `elemSize()`, matching
`pad2_layer.cpp`.
**Two further fixes:** signed-overflow UB in the int64 `Power`/`Neg` path (`sp[i] * scale` is undefined at
`INT64_MIN`, now multiplied through `uint64_t`), and `CV_OCL_RUN` now skips integer depths, since the OCL
activation kernels are float math and `CV_32S` would have gone through a 24-bit mantissa.
**New accuracy tests in `test_int.cpp`**: `Test_Abs_Int`, `Test_Sign_Int`, `Test_Neg_Int`, `Test_Scatter_Int`,
`Test_GatherND_Int`, with `Test_GatherElements_Int` and `Test_ScatterND_Int` widened to nine depths.
Removed `test_slice_start_out_of_bounds` from the parser denylist.
### 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
feat: support boolean (CV_Bool) images in imwrite - #29407
## Summary
`imwrite` failed on `CV_Bool` (boolean) images because no encoder handles that depth. This normalizes a boolean image to `CV_8U` (mapping true to 255) before encoding, so boolean masks can be written directly instead of requiring a manual `convertTo` at every call site.
Adds round-trip tests covering boolean-image encoding.
Fixes#29365
AI was used for assistance.
Imgproc test cleanup - #29740
co-authored by: @Prasadayus
### Re-enabled as-is (stale disable reasons)
- `FillPolyFully.fillpoly_fully` (`test_drawing.cpp:1142`)
- `Resize_Bitexact` (`test_resize_bitexact.cpp:188`, 4 instantiations): `INTER_NEAREST` and
`INTER_NEAREST_EXACT` agree exactly at integer upscale factors; measured 0.0 diff on all 4.
### Add assertions
- **imgproc** — new `Imgproc_Watershed.regression`: `cv::watershed` had no working coverage at all.
### 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
Objdetect test cleanup - #29741
co-authored by: @Prasadayus
### Given real assertions
| change | reason |
|---|---|
| new `Objdetect_CheckChessboard.accuracy` (`test_checkchessboard.cpp`) | `cv::checkChessboard`'s only validation lived inside a test named `timing`, which aborted at the first of 19 images. The new test iterates all 19 from `chessboard_timing_list.dat` with `SCOPED_TRACE` and `EXPECT_EQ`, so every image is reported instead of stopping at the first mismatch |
| deleted `test_chesscorners_timing.cpp` | what remained after extracting the assertions was a stopwatch — it measured `findChessboardCorners` and asserted nothing about the result |
### Re-enabled - the reason for disabling no longer holds
| test | reason |
|---|---|
| `Charuco.testSeveralBoardsWithCustomIds` (`test_charucodetection.cpp:922`) | disabled by #24338 because 5.x returns charuco corners as `32FC2` rather than `2×32FC1` (#23473). The test never compares shapes: it asserts `expected_corners.total() == c_corners.total() * c_corners.channels()` and then compares `expected_corners.reshape(1, 1)` against `c_corners.reshape(1, 1)` — both flattened to one row, so the channel layout cannot affect the result. The comparison was already made shape-agnostic; only the `DISABLED_` prefix was never removed |
### 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
Linear and Flex attention layers support - #29624
### 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
Add Image Decoder ONNX Layer - #29785
### 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