【问题标题】:opencv matrix brace operatoropencv矩阵大括号运算符
【发布时间】:2012-07-29 20:10:18
【问题描述】:

我注意到在许多示例/教程中人们使用大括号运算符“()”进行矩阵访问,这在某些情况下让我感到困惑。

问题是: 假设我们有一个名为 M 的 n*m 矩阵(例如 3x4)。通过“M(0)”或“M(1)”或大括号内的任何其他奇异参数访问它会返回哪些元素?我认为您应该同时指定行和列(如“M(0,1)”或类似的东西)。

【问题讨论】:

  • 你能举出一个例子吗?
  • Mat_<double> X(4,1); Mat_<double> X_(4,1); (...) // A is a 4x3 matrix, B is a 4x1 matrix cv::solve(A,B,X_,DECOMP_SVD); X(0) = X_(0); X(1) = X_(1); X(2) = X_(2); X(3) = 1.0;

标签: opencv matrix operator-keyword


【解决方案1】:

你看到的是线性索引访问——即直接以线性方式访问内存。

在矩阵中,所有元素都存储在一大块内存中,每一行都在前一行之后。这就是为什么,如果你想访问(i, j) 位置的元素,你会写一些类似

elem = matrix(j + rowWidth*i)

但你可以简单地访问它

elem = matrix(k)

当您不关心行/列位置时,这很有用,例如当您对矩阵中的所有元素求和时:

count = width*height;
sum=0;
for(i=0;i<count;i++)
    sum+=matrix(i);

或者当您预先计算线性索引时。

请注意,如果矩阵碰巧没有存储在连续的内存块中(例如更大矩阵中的感兴趣区域),这种技术可能会产生一些最疯狂的错误。在使用线性索引之前,请务必检查 if (myMat.isContinuous())

【讨论】:

  • 如果我有类似 "M.at(0)" 或 "M.at(0)" 的东西怎么办? Opencv 参考文献指出“at”方法需要一个 2d 点或两个索引(用于行和列)。但是,显然,我发现的代码只使用了 1 个参数并且可以成功运行。我不明白幕后发生了什么:在这种情况下,究竟访问了哪个矩阵元素?
  • 有两个at&lt;&gt; 运算符,其中一个可能没有记录,它的工作原理如上所述
  • 当 () 运算符的参数是 cv::Rect 类型时怎么样?
【解决方案2】:

这是来自 OpenCV 2.4.2

template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0, int i1)
{
    return ((_Tp*)(data + step.p[0]*i0))[i1];
}
template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0)
{
    return this->at<_Tp>(i0);
}
template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2)
{
    return this->at<_Tp>(i0, i1, i2);
}

这是Mat::at(int i0) 的定义,Mat_ 公开继承自 Mat

template<typename _Tp> inline const _Tp& Mat::at(int i0) const
{
    if( isContinuous() || size.p[0] == 1 )
        return ((const _Tp*)data)[i0];
    if( size.p[1] == 1 )
        return *(const _Tp*)(data + step.p[0]*i0);
    int i = i0/cols, j = i0 - i*cols;
    return ((const _Tp*)(data + step.p[0]*i))[j];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-03
    • 1970-01-01
    • 2019-10-04
    • 2012-05-18
    • 1970-01-01
    相关资源
    最近更新 更多