2

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

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

4

2 回答 2

7

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

在矩阵中,所有元素都存储在一大块内存中,每一行都在前一行之后。这就是为什么,如果你想在(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())在使用线性索引之前务必检查!

于 2012-07-30T09:05:38.477 回答
0

这是来自 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];
}
于 2012-08-01T07:04:30.163 回答