-
-
Notifications
You must be signed in to change notification settings - Fork 56.5k
Open
Labels
Milestone
Description
#8413 issue forces to use IEEE 754 rules for floating points.
#12826 implements that (OpenCV 4.0.0).
However there is implicit conversion to float+ type if src/dst types does not match:
opencv/modules/core/src/arithm.cpp
Lines 696 to 697 in 4223495
| wtype = std::max(depth1, std::max(depth2, CV_32F)); | |
| wtype = std::max(wtype, dtype); |
So processing is performed by IEEE rules, which may emit Inf/NaN values.
Conversion of result float values to destination of integer signed type (8S/16S/32S) may emit "min" values (-128, -32768, INT_MIN) which may be not expected by Users.
Problem comes from cvRound(nan/inf/int32 overflow/int32 underflow) => INT_MIN (-2147483648)
std::cout << cvRound(std::numeric_limits<float>::quiet_NaN()) << std::endl;
std::cout << cvRound(std::numeric_limits<float>::infinity()) << std::endl;
std::cout << cvRound(-std::numeric_limits<float>::infinity()) << std::endl;
std::cout << cvRound(1e30f) << std::endl;
std::cout << cvRound(-1e30f) << std::endl;
Test code:
cv::Mat m1(N, N, CV_8S, Scalar::all(1));
cv::Mat m2(N, N, CV_8U, Scalar::all(0));
Mat dst;
int dstType = CV_8S;
double scale = 2.5;
cv::divide(m1, m2, dst, scale, dstType);
std::cout << dst.type() << std::endl << dst << std::endl; // -128
The same types works as documented:
cv::Mat m1(N, N, CV_8S, Scalar::all(1));
cv::Mat m2(N, N, CV_8S, Scalar::all(0));
Mat dst;
int dstType = CV_8S;
double scale = 2.5;
cv::divide(m1, m2, dst, scale, dstType);
std::cout << dst.type() << std::endl << dst << std::endl; // 0 as expected
Reactions are currently unavailable