1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-21 19:33:03 +04:00
sujal 62930a207b Merge pull request #28920 from 5usu:fix/28798-yunet-int8-objbranch
dnn: skip Conv2Int8 fusion for grouped convs with Kg<8 (#28798) #28920

OpenCV Extra: https://github.com/opencv/opencv_extra/pull/1360

- [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

---

Fixes #28798.

The YuNet 2023mar int8 model from opencv_zoo doesn't detect anything on 5.x. With `--score_threshold
0.05` the detector still returns no boxes, so it's not just a confidence drop — the network output is
broken.

After dumping intermediate tensors and comparing against onnxruntime, the `obj_*` branches collapse to
~0 (saturated int8 `-128`), and the `cls_*` branches saturate the other way. Final score is `cls * obj`
so nothing ever crosses threshold.

The cause is in `Conv2Int8`'s VNNI kernel. It processes `K0 = 8` output channels per SIMD iteration and
writes them as one `K0`-wide block to `out + (n*K1 + k1)*planesize` with `k1 = k_base / K0`. When
`ngroups > 1` and `Kg = K/ngroups < K0`, consecutive groups share the same `k1` slot and overwrite each
other — only the last group's result survives. YuNet has six `1x1x3x3` depthwise conv heads (`Kg = 1`),
which is exactly this case.

The unfused `DequantizeLinear → Conv2 → QuantizeLinear` path is fine. The minimal fix here is to skip
the rewrite to `Conv2Int8` when `Kg < 8` so we fall back to the float path. A proper depthwise int8
kernel can be added later as a separate optimization.

Verified with `samples/dnn/face_detect.py` on Lena:

Before:
AssertionError: Cannot find a face in samples/data/lena.jpg

After:
Face 0, top-left coordinates: (204, 187), box width: 149, box height 212, score: 0.89

Cross-check vs onnxruntime: `cls_8` mean `0.673` (was `0.93`, ORT `0.673`), `obj_8` max `0.0039` (was
`0`, ORT `0.0039`).

The regression test is a single 16-group depthwise `QLinearConv` with non-zero `x_zp`, added to
`Quantized_Convolution`. Test data is in opencv_extra on the matching branch (~9 KB total).

  
<img width="1864" height="1060" alt="image" src="https://github.com/user-attachments/assets/a1b15c64-6b84-42b1-86a4-1d55474cb38c" />
2026-05-25 09:48:59 +03:00
2026-05-20 17:57:51 +03:00
2026-05-20 17:57:51 +03:00
2026-05-20 17:57:51 +03:00
2026-05-20 17:57:51 +03:00
2018-10-11 17:57:51 +00:00
2025-08-07 10:35:20 +03:00
2024-04-02 16:39:54 +03:00

OpenCV: Open Source Computer Vision Library

Resources

Contributing

Please read the contribution guidelines before starting work on a pull request.

Summary of the guidelines:

  • One pull request per issue;
  • Choose the right base branch;
  • Include tests and documentation;
  • Clean up "oops" commits before submitting;
  • Follow the coding style guide.

Additional Resources

S
Description
No description provided
Readme Apache-2.0 3.3 GiB
Languages
C++ 87.6%
C 3.2%
Python 2.9%
CMake 2%
Java 1.5%
Other 2.6%