繁体   English   中英

在opencv中划分两个矩阵

[英]divide two matrices in opencv

我想对两个 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 时,不应用饱和度。 在溢出的情况下,您甚至可能得到错误符号的结果。

saturate() 函数有什么作用? 我可以对 CV_32S 矩阵安全地使用 Division(A,B,C) 吗? divide() 与 / 运算符有何不同?

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

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

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

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

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

所以, operator/cv::divide实际上应该是一样的,只不过操作符会返回一个矩阵表达式,它的求值被延迟了。 最后, operator/也将调用cv::divide ,如这里的一个简单案例所示。 尤其是结果应该是平等的。

不过,结果可能会令人惊讶。 使用两个整数矩阵进行除法,结果将类似于在浮点算术中完成的,然后是舍入到最接近的整数,更喜欢偶数(另请参见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 (正如您在文档中所述),但还要注意四舍五入 (四舍五入)和抢七局-1-2 同时抢七局-3-2 (平局平局)。


注意:两个浮点类型矩阵没有定义任何特殊行为,而是在被零除的情况下计算为 -inf、nan 或 inf。 当您将两个浮点矩阵相除但请求整数结果时,这甚至成立。 在这种情况下,-inf、nan 和 inf 将转换为最小值,这可能是一个错误(或者只是未由 OpenCV 定义)。


整数除法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