简体   繁体   English

在opencv中划分两个矩阵

[英]divide two matrices in opencv

I would like to perform a element-wise division of two opencv CV_32S matrices (A & B).我想对两个 opencv CV_32S 矩阵(A 和 B)执行元素划分。

I want C = A/B when B is not 0, 0 otherwise.当 B 不为 0 时,我想要 C = A/B,否则为 0。

But I'm not sure to understand opencv documentation:但我不确定是否了解 opencv 文档:

http://docs.opencv.org/modules/core/doc/operations_on_arrays.html#divide 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.当 src2(I) 为零时,dst(I) 也将为零。 Different channels of multi-channel arrays are processed independently.多通道阵列的不同通道独立处理。

Note Saturation is not applied when the output array has the depth CV_32S.注意 当输出数组的深度为 CV_32S 时,不应用饱和度。 You may even get result of an incorrect sign in the case of overflow.在溢出的情况下,您甚至可能得到错误符号的结果。

What does the saturate() function? saturate() 函数有什么作用? Can I use divide(A,B,C) safely with CV_32S matrices?我可以对 CV_32S 矩阵安全地使用 Division(A,B,C) 吗? How is divide() different from the / operator? divide() 与 / 运算符有何不同?

===== EDIT AFTER TEST ===== ===== 测试后编辑 =====

My test showed that the / operator does exactly what I want: C = A/B when B != 0, 0 otherwise.我的测试表明 / 运算符完全符合我的要求:C = A/B 当 B != 0 时,否则为 0。

saturate_cast prevents overflows for some data types, so that pixel values 200+200 are reduced to 255 for CV_8U for example (otherwise there would be an overflow and maybe unexpected values occur). saturate_cast 可防止某些数据类型溢出,例如, 255 for CV_8U ,像素值200+200将减少到255 for CV_8U (否则会发生溢出,并且可能会出现意外值)。

Have a look at the link if you want to know more about saturate_cast.如果您想了解更多关于 saturate_cast 的信息,请查看链接。 http://docs.opencv.org/modules/core/doc/intro.html#saturation-arithmetics http://docs.opencv.org/modules/core/doc/intro.html#saturation-arithmetics

Since integer division always reduces the absolute values, there should no overflows occur in integer division (or am I missing something?), so you should be safe I guess.由于整数除法总是减少绝对值,整数除法中不应该发生溢出(或者我错过了什么?),所以我猜你应该是安全的。

So, operator/ and cv::divide should be actually the same, except that the operator will return a matrix expression, whose evaluation is delayed.所以, operator/cv::divide实际上应该是一样的,只不过操作符会返回一个矩阵表达式,它的求值被延迟了。 Finally, also operator/ will call cv::divide , as can be seen eg for a simple case here .最后, operator/也将调用cv::divide ,如这里的一个简单案例所示。 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() ).使用两个整数矩阵进行除法,结果将类似于在浮点算术中完成的,然后是舍入到最接近的整数,更喜欢偶数(另请参见nearbyint() )。 As an example, using two 6x6 integer matrices, you will get例如,使用两个 6x6 整数矩阵,您将得到

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请注意div-by-0-equals-0 (as you stated from the documentation), but also note (正如您在文档中所述),但还要注意四舍五入 (rounding) and (四舍五入)和抢七局-1-2 while同时抢七局-3-2 (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.注意:两个浮点类型矩阵没有定义任何特殊行为,而是在被零除的情况下计算为 -inf、nan 或 inf。 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).在这种情况下,-inf、nan 和 inf 将转换为最小值,这可能是一个错误(或者只是未由 OpenCV 定义)。


Code for integer division div.cpp (compile with g++ -std=c++11 div.cpp -o div -lopencv_core ):整数除法div.cpp代码(使用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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM