core: vectorize masked norm/normDiff for remaining depths - #29815
### Summary
- The masked `cv::norm()` / `cv::norm(a, b)` kernels in `norm.simd.hpp` had SIMD specializations only for `uchar`, `ushort` and `float`.
- `schar`, `short`, `int`, `double` and `uchar` L2 paths uses the scalar implementation.
### Changes
- Added new vectorized implementations of MaskedNorm{Inf,L1,L2}_SIMD for schar, short, int, and double.
- Added new vectorized implementation of MaskedNormL2_SIMD<uchar, int>.
- Added new MaskedNormDiff{Inf,L1,L2}_SIMD implementations for double.
- Added cn == 4 v_load_deinterleave paths to the uchar L1/L2 kernels.
- Replaced the single f64 accumulator in MaskedNormL1_SIMD<float,double> with four independent ones, so the widening adds can overlap instead of each waiting on the previous.
### Performance Benchmarks
<img width="715" height="709" alt="image" src="https://github.com/user-attachments/assets/46afea06-df98-4dd4-a346-dc8cd4a065c9" />
imgproc: optimize PyrDownVecH<uchar,int,3> using v_load_deinterleave - #29811
**Summary:**
- buildPyramid on Windows-ARM64 (1920×1080, 8UC3) was ~7× slower than x64.
- Root cause: PyrDownVecH<uchar,int,3> used vx_lut_quads to gather pixels, which on NEON compiles to 80 scalar byte reads per SIMD iteration filling a stack buffer one byte at a time before loading it as a vector. The SIMD unit was effectively idle.
**Root Cause:**
- The 3-channel horizontal pass needs 5 non-contiguous source pixels per output pixel. The existing code precomputes byte-offset index arrays and calls vx_lut_quads(src, idx) five times per loop body. On NEON, vx_lut_quads is implemented as 16 individual scalar reads → vld1q_s8, so 5 calls = 80 scalar loads producing only 12 int32 outputs.
**Fix:**
- Replace the gather loop with v_load_deinterleave, which maps to vld3q_u8 on AArch64 — single instruction, loads 48 bytes and hardware-deinterleaves R/G/B in one shot
**Performance Benchmarks:**
<img width="1021" height="536" alt="image" src="https://github.com/user-attachments/assets/6c4b5d71-d096-4dfd-9bc4-4315d4e679af" />
core: fix unsigned Rect intersection for disjoint rectangles (#11988) - #29069Fixes#11988
## Problem
`Rect_<_Tp>::operator&` / `operator&=` returned a non-empty rectangle when two **unsigned** rectangles do not overlap.
### Example:
```cpp
cv::Rect_<unsigned> r1(0, 0, 1, 1);
cv::Rect_<unsigned> r2(2, 2, 1, 1);
auto inter = r1 & r2; // was [1 x 1 from (2, 2)], expected empty
```
Root cause: the previous implementation subtracted edge coordinates before checking overlap. For `unsigned _Tp`, expressions like `width - (x_max - x_min)` can underflow when rectangles are disjoint.
### Solution
Add a check for underflow
### Tests
Added regression test `Core_Rect.test_unsigned_overflow in modules/core/test/test_misc.cpp`.
Speed up imgproc warpAffine and warpPerspective for BORDER_TRANSPARENT - #29779
### 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
- [ ] 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
## Why
I was using `warpPerspective` to draw several source images on a large destination image in mode `BORDER_TRANSPARENT` and ran into `warpPerspective` being surprisingly slow. Upon reading the code, it turns out that `warpPerspective`, as well as `warpAffine`, iterates over all the destination image's pixels even if the source image gets projected to only a small part of the destination image, resulting in considerable overhead for my use case. I believe other users would also benefit from making this case more efficient.
## Changes
d19c343704 calculates the ROI of the source image in the destination image and then limits the destination image walk to that area. Given that the existing tests didn't cover `BORDER_TRANSPARENT`, I extended that in e451f59cda. Next to that, I added a small performance test dedicated to this use case (c4e271c2dc).
## Performance improvement
The following table show the timing difference before and after, generated using the added perf test (source image projects to 64x64, drawn in a 512x512 destination image):
| function | type | interp | base [ms] | opt [ms] | speedup |
| --- | --- | --- | --- | --- | --- |
| warpAffine | 8UC1 | NEAREST | 0.204 | 0.010 | 19.8× |
| warpAffine | 8UC1 | LINEAR | 0.428 | 0.026 | 16.6× |
| warpAffine | 8UC4 | NEAREST | 0.239 | 0.021 | 11.5× |
| warpAffine | 8UC4 | LINEAR | 0.433 | 0.031 | 14.0× |
| warpPerspective | 8UC1 | NEAREST | 0.759 | 0.033 | 23.2× |
| warpPerspective | 8UC1 | LINEAR | 1.125 | 0.067 | 16.8× |
| warpPerspective | 8UC4 | NEAREST | 0.786 | 0.040 | 19.5× |
| warpPerspective | 8UC4 | LINEAR | 1.110 | 0.101 | 11.0× |
In short, a 10 to 20x speedup.
## Notes
- This is my first PR for the OpenCV project, I'm sorry in case I didn't respect all contribution guidelines.
- If relevant, Clause Opus 4.8 was used for exploring the codebase, some code and style suggestions and review.
objdetect: do not modify the input features in FaceRecognizerSF::match - #29804
`FaceRecognizerSF::match()` normalizes its two `InputArray` features in place, writing
through to the caller's buffers, and returns a wrong score when the two overlap.
### Fix
Normalize both features into their own destinations. This yields bit-exact the same
values as the in-place form, checked across a range of shapes and depths including a
non-continuous ROI, so scores for non-overlapping inputs do not move.
### 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
- [ ] There is a reference to the original bug report and related work (no issue reports this; #7298 is the related RFC)
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable (accuracy test added in-repo; it reuses the existing model, so there is no opencv_extra patch)
- [ ] The feature is well documented and sample code can be built with the project CMake (n/a — bug fix, no API, sample or documentation change)
Extract IPP integration as HAL function for bilateral_filter - #29410
Backport of https://github.com/opencv/opencv/pull/29409
**Performance Numbers on Intel(R) Core(TM) i9-11900K:** https://docs.google.com/spreadsheets/d/1rmNB3X_V8rWttUGBqXRs1FmkxeKR0O93x_ez5tVjutY/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
Remove Intel-only gates from dedicated 3x3/5x5 GaussianBlur kernels and
single-pass separable filter paths so AMD and other OpenCL devices can
use the same optimized implementations with existing fallbacks.
imgproc: Extended spatialGradient API and applied to different detector algorithms - #29273
imgproc: Add fused Sobel2D gradient API and use it in different detector algorithms
Add a public Sobel2D API computing dx/dy in a single fused pass with 3x3 and 5x5 kernels (SIMD-dispatched). The float (CV_32F) path folds the output scale and float store into the kernel, avoiding a separate convertTo pass.
- Add runtime SIMD dispatch for the Canny edge path.
- Integrate fused Sobel2D into:
- Canny
- cornerEigenValsVecs (cornerHarris, cornerMinEigenVal, cornerEigenValsAndVecs, goodFeaturesToTrack)
- GeneralizedHough
- IntelligentScissors
- HoughCircles
- Add performance and accuracy tests.
### 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
- [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
calib3d: fix division by zero in SGBM 3-way mode when uniquenessRatio is 100 - #29762Fixes#29761.
`SGBM3WayMainLoop` derives its uniqueness threshold in the SIMD path as `(100*min_cost)/(100-uniquenessRatio)`, so a `uniquenessRatio` of 100 divides by zero and the process dies with SIGFPE. The scalar fallback right below it, and the other SGBM modes, express the same test as `cost*(100 - uniquenessRatio) < min_cost*100`, which needs no division and copes with the value fine. `MODE_HH4` goes through `CalcHorizontalSums`, which never divides, so only `MODE_SGBM_3WAY` reproduces.
The SIMD shortcut is now skipped once `uniquenessRatio` reaches 100 and the scalar loop decides on its own, which is exactly what a build without SIMD already does. Ratios below 100 keep the fast path and produce identical output. The diff looks long because the existing block is indented one level, `?w=1` shows the real change.
The second commit fixes the neighbouring case: `thresh` grows to `100*min_cost` as the ratio approaches 100, well past `SHRT_MAX`, and `(short)(thresh+1)` wraps. On the reporter's image pair at ratio 99, 3-way marked 48723 pixels valid while `MODE_SGBM`, `MODE_HH` and `MODE_HH4` all landed near 48370; saturating brings it to 48371.
Verified with opencv_extra test data: `Calib3d_StereoSGBM.regression`, `Calib3d_StereoSGBM.deterministic`, `Calib3d_StereoSGBM_HH4.regression` and `Calib3d_StereoBM.regression` still pass. The new `Calib3d_StereoSGBM.regression_29761` aborts on unpatched 4.x under `-fsanitize=integer-divide-by-zero` and passes with the fix.
The same code sits at `modules/stereo/src/stereosgbm.cpp` on 5.x, which is the path the reporter cited. The module move means the merge will not apply cleanly, so tell me if you would rather have a separate 5.x PR.
### 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
Optimize fastGEMM1T NEON: extend 4-wide to 8-wide outer loop unrolling - #29716
**PR Description:**
- This PR extends the NEON fastGEMM1T optimization by adding an 8-wide outer loop before the existing 4-wide loop. The 8-wide block processes 8 output neurons per iteration instead of 4, reducing the total number of outer loop iterations by half and sharing the vector load cost across 8 output accumulator registers instead of 4.
- On x86, the AVX2 path processes 8 floats per instruction (256-bit registers) and AVX-512 processes 16 floats per instruction (512-bit registers). On ARM, NEON is 128-bit, only 4 floats per instruction. Intel's wider registers naturally cover more outputs per inner step. This patch brings ARM NEON closer to Intel parity through wider outer loop unrolling.
**Performance results:**
<img width="1236" height="478" alt="image" src="https://github.com/user-attachments/assets/c933e64c-2200-450e-9887-3fd0cbdd5b8e" />
Notes:
- The existing 4-wide loop is retained to handle remainders when nvecs is not a multiple of 8
- No existing tests modified
- Follows the same pattern as the existing 4-wide NEON path.
- [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
Same as #29757 in 5.x
The Python tutorial sample thresholds the orientation with a single cv.threshold call, passing HighThr as the maxval argument rather than as an upper bound:
```_, imgOrientationBin = cv.threshold(imgOrientation, LowThr, HighThr, cv.THRESH_BINARY)```
That computes imgOrientation > LowThr ? HighThr : 0, so HighThr never restricts the angle. The C++ counterpart uses inRange(imgOrientation, Scalar(LowThr), Scalar(HighThr), imgOrientationBin), and the tutorial text states "LowThr and HighThr define orientation range", so the C++ behaviour is the intended one.
core: fix JacobiSVD SIMD accumulation to match scalar path - #29727
Replace FMA with mul-add in dotD/givensD to avoid Windows MSVC rounding drift.
- Address the FMA drift introduced in https://github.com/opencv/opencv/pull/29720
### 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
- [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
* The condition under which the test `AsyncAPICancelation/cancel/0.basic` doesn't compile using GCC 11 is narrowed down to the only GCC versions which are affected: GCC 11.0 and 11.1. The issue was fixed in GCC 11.2 (verified using 11.2.0, 11.3.0, 11.4.0, 11.5.0, 12.1.0 versions of GCC).
* The corresponding issue: opencv/opencv#19678.
CV_Assert permits rvec/tvec as Size(1,3) or Size(3,1), but the
implementation only handled column vectors:
- LM path read rvec/tvec via .at<double>(i,0), OOB for a row vector.
- LM path's convertTo() write-back reallocated a local Mat alias
instead of writing in place whenever the source/dest shapes
mismatched, silently discarding the refined result for row vectors.
- VVS path's "R1 * tvec" requires a column vector; a row vector threw
a cv::Exception from gemm's shape assertion.
Fixed all three with shape-agnostic .at<double>(i) indexing and
reshape() before convertTo()/matrix arithmetic so orientation always
matches. Added Calib3d_SolvePnP.refine_row_vector covering both
solvePnPRefineLM and solvePnPRefineVVS with both orientations.
Fixes#29747
imgproc: avoid NaN in masked TM_CCOEFF_NORMED for constant templates - #29071
### 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
### Summary
Fixes#23257.
This patch handles a degenerate masked `TM_CCOEFF_NORMED` case in `matchTemplate()`. When the template is constant over the effective mask area, the template norm can become zero or NaN, which may propagate NaN/Inf values into the result. The masked path now returns all ones for this case, matching the existing behavior of the unmasked `TM_CCOEFF_NORMED` implementation for constant templates.
### Tests
- `cmake --build build_project4 --target opencv_test_imgproc -j4`
- `./build_project4/bin/opencv_test_imgproc '--gtest_filter=Imgproc_MatchTemplateWithMask.regression_23257_constant_template'`
- `./build_project4/bin/opencv_test_imgproc '--gtest_filter=*MatchTemplate*'`
The MatchTemplate-related test filter ran 147 tests successfully.
allow cv::resize to support more than 4 channels in AREA path - #29691
Fixes #29651
### 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
Extracted IPP to HAL for getRectSubPix function in 4.x - #29512
### 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
imgproc: Optimize AVX-512 path for accumulate - #29718
- Add AVX512_SKX/AVX512_ICL to accum dispatch
- Video_RunningAvg.accuracy failure observed in #29394 has been fixed.
### 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
- [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 VBLAS::dotD and VBLAS::givensD to vectorize JacobiSVDImpl_'s dot-product,
Givens rotation and norm loops with double-precision accumulation matching the
scalar path.
Dispatch lapack for both AVX512_SKX and AVX512_ICL.