2014-01-07 66 views
2

我想执行两个opencv CV_32S矩阵的元素方式划分(A & B)。在opencv中划分两个矩阵

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

但我并不一定要了解OpenCV的文档:

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

它说:

当SRC2(我)是零,DST(我)也将是零。多通道阵列的不同通道是独立处理的。

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

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

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

我的测试表明,/运营商不正是我想要的:C = A/B时,B = 0,否则为0!

回答

2

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

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

由于整数除法总是减小绝对值,所以在整数除法中不应该发生溢出(或者我是否遗漏了某些东西?),所以你应该是安全的。

+0

THX!divide()与/运算符有什么不同? –

+0

维基百科:“数字2,147,483,647是计算中32位有符号整数的最大值”。因此,如果您划分两个32F元素,并且目标32S的结果为溢出,则会发生意外行为。但是,对于输入32S矩阵,您是安全的。 您需要重载cv :: Mat的运算符/方法来实现其他行为。 – baci

+0

我不知道如何划分不同于标准/运营商。也许他们转换为float并使用SSE指令,或者他们可能在内部使用/操作符,也许你可以在openCV源代码中找到这些部分;) – Micka

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-2tie-break-3-2(抢七连)。


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