divide two matrices in opencv
c++, matrix, opencv
Solution
So, `operator/` and `cv::divide` should be actually the same, except that the operator will return a matrix expression, whose evaluation is delayed. Finally, also `operator/` will call `cv::divide`, as can be seen e. g. for a simple case here. Especially the results should be equal.
Still, the results can be surprising. Using two integer matrices for division, the result will be like done in floating point arithmetic followed by a round to nearest integer preferring even numbers (see also `nearbyint()`). As an example, using two 6x6 integer matrices, you will get
0/0 == 0 1/0 == 0 2/0 == 0 3/0 == 0 4/0 == 0 5/0 == 0
0/1 == 0 1/1 == 1 2/1 == 2 3/1 == 3 4/1 == 4 5/1 == 5
0/2 == 0 1/2 == 0 2/2 == 1 3/2 == 2 4/2 == 2 5/2 == 2
0/3 == 0 1/3 == 0 2/3 == 1 3/3 == 1 4/3 == 1 5/3 == 2
0/4 == 0 1/4 == 0 2/4 == 0 3/4 == 1 4/4 == 1 5/4 == 1
0/5 == 0 1/5 == 0 2/5 == 0 3/5 == 1 4/5 == 1 5/5 == 1
Note the (as you stated from the documentation), but also note (rounding) and while (tie break to even).
Beware: Two floating point type matrices do not define any special behavior, but rather evaluate to -inf, nan or inf in case of division by zero. This even holds, when you divide two floating point matrices, but requesting an integer result. In that case -inf, nan and inf will translate to the minimum value, which might be a bug (or just not defined by OpenCV).
Code for integer division `div.cpp` (compile with `g++ -std=c++11 div.cpp -o div -lopencv_core`):
#include <opencv2/opencv.hpp>
#include <iostream>
#include <cstdint>
int main() {
cv::Mat i1(6,6,CV_32S);
cv::Mat i2(6,6,CV_32S);
for (int y = 0; y < i1.rows; ++y) {
for (int x = 0; x < i1.cols; ++x) {
i1.at<int32_t>(y, x) = x;
i2.at<int32_t>(y, x) = y;
}
}
cv::Mat q;
cv::divide(i1, i2, q);
// q = i1 / i2;
for (int y = 0; y < q.rows; ++y) {
for (int x = 0; x < q.cols; ++x)
std::cout << x << "/" << y << " == " << q.at<int32_t>(y, x) << "\t";
std::cout << std::endl;
}
return 0;
}
Problem
I would like to perform a element-wise division of two opencv CV_32S matrices (A & B). I want C = A/B when B is not 0, 0 otherwise. But I'm not sure to understand opencv documentation: http://docs.opencv.org/modules/core/doc/operations_on_arrays.html#divide It says: When src2(I) is zero, dst(I) will also be zero. Different channels of multi-channel arrays are processed independently. Note Saturation is not applied when the output array has the depth CV_32S. You may even get result of an incorrect sign in the case of overflow. What does the saturate() function? Can I use divide(A,B,C) safely with CV_32S matrices? How is divide() different from the / operator? ===== EDIT AFTER TEST ===== My test showed that the / operator does exactly what I want: C = A/B when B != 0, 0 otherwise.