在opencv中划分两个矩阵

时间:2014-01-07 15:24:57

标签: c++ opencv matrix

我想对两个opencv CV_32S矩阵(A& B)进行逐元素划分。

当B不为0时我想要C = A / B,否则为0。

但我不确定了解opencv文档:

http://docs.opencv.org/modules/core/doc/operations_on_arrays.html#divide

它说:

  

当src2(I)为零时,dst(I)也将为零。多通道阵列的不同通道是独立处理的。

     
    

注意当输出数组的深度为CV_32S时,不应用饱和度。在溢出的情况下,您甚至可能得到错误符号的结果。

  

饱和()功能是什么?我可以使用CV_32S矩阵安全地使用除(A,B,C)吗? divide()与/运算符有何不同?

=====测试后编辑=====

我的测试显示/运算符完全符合我的要求:当B!= 0时,C = A / B,否则为0。

2 个答案:

答案 0 :(得分:2)

saturate_cast可以防止某些数据类型出现溢出,例如像素值200+200减少到255 for CV_8U(否则会出现溢出,可能会出现意外值)。

如果您想了解有关saturate_cast的更多信息,请查看该链接。 http://docs.opencv.org/modules/core/doc/intro.html#saturation-arithmetics

由于整数除法总是减少绝对值,所以整数除法不应该出现溢出(或者我错过了什么?),所以我猜你应该是安全的。

答案 1 :(得分:0)

因此,operator/cv::divide实际应该是相同的,除了运算符将返回矩阵表达式,其评估被延迟。最后,operator/也会调用cv::divide,如可以看到的那样。 G。对于一个简单的案例here。特别是结果应该是平等的。

但结果仍然令人惊讶。使用两个整数矩阵进行除法,结果将类似于浮点运算,然后是round to nearest integer优选偶数(参见nearbyint())。例如,使用两个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

请注意div-by-0-equals-0(正如您在文档中所述),但请注意rounding(四舍五入)和tie-break-1-2 tie-break-3-2(平均值为偶数)。< / p>

代码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;
}