1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-27 22:33:03 +04:00
Files
Teddy-Yangjiale 3803eb828e Merge pull request #29440 from Teddy-Yangjiale:rvv-k1-06-filter-cov
imgproc: extend boxFilter / gaussianBlurBinomial coverage in RISC-V RVV HAL #29440

### Summary

This PR extends RVV HAL coverage of the two most frequently used smoothing filters. Previously, `cv_hal_boxFilter` was only implemented for single-channel types (plus 32FC3) at 3×3/5×5, and `cv_hal_gaussianBlurBinomial` for 8UC1/16UC1/8UC4. The most common cases in practice — interleaved **8UC3** images and **7×7** box kernels — fell back to the core `FilterEngine` path, which runs single-threaded, costing 6–19× on multi-core RISC-V hardware.

New coverage:

- `boxFilter`: **8UC3 / 8UC4** (3×3, 5×5, 7×7); **7×7** for 8UC1, 16SC1, 32FC1, 32FC3 and the 8U→16U variant
- `gaussianBlurBinomial`: **8UC3** (3×3, 5×5)

Combinations already covered upstream keep their existing kernels byte-for-byte; net diff is +274/−162 across two files.

### Implementation

1. **Channel-blind "flat" kernels** (`boxFilterFlat8U<ksize, cn>`, `gaussianBlurFlat8U<ksize, cn>`). An interleaved row is processed as `width*cn` flat u8 elements whose horizontal taps sit at strides of `cn` elements: element *i* sums exactly its own channel's taps at `i, i+cn, …, i+(ksize−1)·cn`. One template therefore serves all channel counts, and:
   - the horizontal pass becomes `ksize` independent unaligned `vle8` loads combined with widening adds — no `vlseg`/`vsseg` and no serial `vslide1down` chains, which are microcoded/serialized on current RVV hardware;
   - the vertical pass is a single contiguous u16 stream processed at LMUL=8;
   - the output is a plain `vse8` after saturating narrowing.
2. **Incremental vertical sliding window** for box with `ksize > 3`: the column-sum ring buffer keeps `ksize+1` rows so the window slides in O(1) per output row (add the entering row, subtract the leaving row) instead of re-summing `ksize` rows. u16 modular arithmetic stays exact because window sums never exceed 49·255 = 12495.
3. **Division-free normalization**: normalized box output uses multiply-high + shift (`m = ceil(2^18 / k²)`, Granlund–Montgomery; exact for divisors 9/25/49 over the full value range, verified per divisor) instead of long-latency vector integer division. Rounding is bit-identical to the previous `(sum + k²/2) / k²`.
4. **Existing kernels are extended, not rewritten**: `boxFilterC1` and the float `boxFilterC3` gain a 7×7 step in their existing unrolled style, so the 3×3/5×5 instantiations compile to the same code as before. The previous per-channel gaussian 8UC4 segment kernel is replaced by the flat kernel at measured parity, which is why the diff removes more gaussian lines than it adds.
5. Constraints respected: no hard-coded VLEN, RVV 1.0 intrinsics only, no scalable vector types in arrays.

### Performance

SpacemiT K1 (X60, rv64gcv, VLEN=256, 8×1.6 GHz), 1280×720, against a clean build of current 5.x HEAD.

**Measurement protocol:** each case is timed for **30 iterations** (after 2 warm-up runs) and the minimum is taken; the whole benchmark is executed in **2 interleaved rounds per library** (baseline/candidate alternated to cancel frequency/thermal drift, measured at up to 2× per run on this board), reporting the per-case minimum across rounds.

| Case | Generic | HAL | Speedup |
|------|--------:|----:|--------:|
| boxFilter 8UC1 7×7 | 6.539 ms | 0.330 ms | 19.8× |
| boxFilter 8UC3 3×3 | 7.325 ms | 0.994 ms | 7.4× |
| boxFilter 8UC3 5×5 | 8.118 ms | 1.142 ms | 7.1× |
| boxFilter 8UC3 7×7 | 15.930 ms | 1.328 ms | 12.0× |
| boxFilter 8UC4 3×3 | 9.552 ms | 1.466 ms | 6.5× |
| boxFilter 8UC4 5×5 | 10.775 ms | 1.841 ms | 5.9× |
| boxFilter 8UC4 7×7 | 14.268 ms | 2.112 ms | 6.8× |
| gaussianBlur 8UC3 3×3 | 2.382 ms | 1.023 ms | 2.3× |
| gaussianBlur 8UC3 5×5 | 2.746 ms | 1.684 ms | 1.6× |

**Geometric mean: ~6.1×** across the newly covered cases. Most of the box gain is the HAL's row-parallel execution (core `FilterEngine` has no internal parallelism) multiplied by the flat-layout kernels; the incremental window gives 7×7 a further ~1.9× over the plain flat version.

Regression check: the full `opencv_perf_imgproc` sweep (5610 timed cases, `--perf_min_samples=10`, one round per library) shows a geomean of 1.015× with no regressions beyond run-to-run noise — every case initially below 0.90× was re-verified with 2×2 interleaved rounds and per-case minima, and none persisted. The blur fixtures independently confirm 4.7–8.6× on 8UC4 across sizes and border types.

### Accuracy

- **Bit-exact against the core fallback**: for every newly covered combination (all 15 type/ksize pairs exercised), the HAL output was checksummed against the generic implementation on identical random inputs — all checksums match exactly. This includes the multiply-high normalization (bit-identical rounding to the previous division) and the incremental vertical window (u16 modular add/subtract cancels exactly).
- **Full accuracy suites**: `opencv_test_imgproc` filter/blur/smooth tests (`*BoxFilter*:*GaussianBlur*:*Blur*:*blur*:*Smooth*:*smooth*`) were run on K1 against a clean upstream HEAD build: **819 tests pass on both libraries, and the failure sets (pre-existing upstream failures, unrelated to this PR) are line-for-line identical**. These suites cover random anchors, all border modes, ROI offsets, and in-place operation.
- Combinations already covered upstream are unchanged by construction (same kernels, same codegen), so their accuracy behavior is inherited.

Note for reviewers: the large baseline gap also reflects that core `FilterEngine` runs single-threaded; that affects all non-HAL targets and may deserve a separate issue.


### 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.
- [ ] The feature is well documented and sample code can be built with the project CMake
2026-07-14 12:16:46 +03:00
..
2018-02-03 19:39:47 +00:00
2018-02-03 19:39:47 +00:00
2018-02-03 19:39:47 +00:00
2025-01-13 16:34:28 +01:00
2019-08-16 17:34:29 +03:00
2018-02-03 19:39:47 +00:00
2018-02-03 19:39:47 +00:00
2019-03-06 15:52:23 +03:00
2018-02-03 19:39:47 +00:00
2018-02-03 19:39:47 +00:00