-
-
Notifications
You must be signed in to change notification settings - Fork 56.5k
[RFC] rounding rule for cv::divide() #24213
Description
System Information
OpenCV version: 4.x branch
Operating System / Platform: Ubuntu 20.04 (Raspi4, arm64)
Compiler & compiler version: GCC 9.3.0
Detailed description
This issue is about cv::divide(). related with #24074
Rounding rule for it is not describled at cv::divide()
In arm64, it works with Round to nearest, ties away from zero
In x86-64, it works with Round to nearest, ties to even.
(Possibly, the behavior may change according to the rounding mode specification of the floating point unit.)
Q. Their results are different. Which are these behaviours correct/better ?
If arm64 behaviours should be fixed...
For arm64, I think it can fix following patch.
However v_round() function seems to used many times.
I feel the risk of breaking backwards compatibility.
I would appreciate it if you could comment on this issue.
before : https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtaq_s64_f64
after : https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnq_s64_f64
diff --git a/modules/core/include/opencv2/core/hal/intrin_neon.hpp b/modules/core/include/opencv2/core/hal/intrin_neon.hpp
index 6f8973231b..14eb180819 100644
--- a/modules/core/include/opencv2/core/hal/intrin_neon.hpp
+++ b/modules/core/include/opencv2/core/hal/intrin_neon.hpp
@@ -1997,12 +1997,12 @@ inline v_int32x4 v_trunc(const v_float32x4& a)
inline v_int32x4 v_round(const v_float64x2& a)
{
static const int32x2_t zero = vdup_n_s32(0);
- return v_int32x4(vcombine_s32(vmovn_s64(vcvtaq_s64_f64(a.val)), zero));
+ return v_int32x4(vcombine_s32(vmovn_s64(vcvtnq_s64_f64(a.val)), zero));
}
inline v_int32x4 v_round(const v_float64x2& a, const v_float64x2& b)
{
- return v_int32x4(vcombine_s32(vmovn_s64(vcvtaq_s64_f64(a.val)), vmovn_s64(vcvtaq_s64_f64(b.val))));
+ return v_int32x4(vcombine_s32(vmovn_s64(vcvtnq_s64_f64(a.val)), vmovn_s64(vcvtnq_s64_f64(b.val))));
}Steps to reproduce
#include <opencv2/core.hpp>
#include <iostream>
int main(void)
{
cv::Mat src1 = (cv::Mat_<uchar>(3,3) << 25,23,0, 0,0,0, 0,0,0 );
std::cout << src1 << std::endl;
cv::Mat dst;
cv::divide(src1, 2, dst );
std::cout << dst << std::endl;
return 0;
}[x86-64]
kmtr@kmtr-VMware-Virtual-Platform:~/work/studyT2$ ./a.out
[ 25, 23, 0;
0, 0, 0;
0, 0, 0]
[ 12, 12, 0;
0, 0, 0;
0, 0, 0]
[arm64]
kmtr@ubuntu:~/work/build4-main/study$ ./a.out
[ 25, 23, 0;
0, 0, 0;
0, 0, 0]
[ 13, 12, 0;
0, 0, 0;
0, 0, 0]Issue submission checklist
- I report the issue, it's not a question
- I checked the problem with documentation, FAQ, open issues, forum.opencv.org, Stack Overflow, etc and have not found any solution
- I updated to the latest OpenCV version and the issue is still there
- There is reproducer code and related data files (videos, images, onnx, etc)