在我们使用Mat类型的对象的时候,有时会想直接获取比如第一行的数据、最后一列的数据等等。Mat数据结构提供了这样的接口给我们使用,接口列表如下:
//! returns a new matrix header for the specified row
[1]Mat row(int y) const;
//! returns a new matrix header for the specified column
[2]Mat col(int x) const;
//! ... for the specified row span
[3]Mat rowRange(int startrow, int endrow) const;
[4]Mat rowRange(const Range& r) const;
//! ... for the specified column span
[5]Mat colRange(int startcol, int endcol) const;
[6]Mat colRange(const Range& r) const;
[1][2]是获取指定某一行或者某一列的数据的接口函数,而[3]-[6]则是获取某连续几行或者几列数据的接口函数。[1]和[2]的定义如下:
inline Mat Mat::row(int y) const { return Mat(*this, Range(y, y+1), Range::all()); }
inline Mat Mat::col(int x) const { return Mat(*this, Range::all(), Range(x, x+1)); }
可以看到,[1][2]都使用了Mat的一个构造函数,这在构造函数那篇博客中没有讲到。这个构造函数的定义如下:
Mat::Mat(const Mat& m, const Range& _rowRange, const Range& _colRange) : size(&rows)
{
initEmpty();
CV_Assert( m.dims >= 2 );
if( m.dims > 2 )
{
AutoBuffer<Range> rs(m.dims);
rs[0] = _rowRange;
rs[1] = _colRange;
for( int i = 2; i < m.dims; i++ )
rs[i] = Range::all();
*this = m(rs);
return;
}
*this = m;
if( _rowRange != Range::all() && _rowRange != Range(0,rows) )
{
CV_Assert( 0 <= _rowRange.start && _rowRange.start <= _rowRange.end && _rowRange.end <= m.rows );
rows = _rowRange.size();
data += step*_rowRange.start;
flags |= SUBMATRIX_FLAG;
}
if( _colRange != Range::all() && _colRange != Range(0,cols) )
{
CV_Assert( 0 <= _colRange.start && _colRange.start <= _colRange.end && _colRange.end <= m.cols );
cols = _colRange.size();
data += _colRange.start*elemSize();
flags &= cols < m.cols ? ~CONTINUOUS_FLAG : -1;
flags |= SUBMATRIX_FLAG;
}
if( rows == 1 )
flags |= CONTINUOUS_FLAG;
if( rows <= 0 || cols <= 0 )
{
release();
rows = cols = 0;
}
}
而[3][4][5][6]都同样调用了这个构造函数:
inline Mat Mat::rowRange(int startrow, int endrow) const
{ return Mat(*this, Range(startrow, endrow), Range::all()); }
inline Mat Mat::rowRange(const Range& r) const
{ return Mat(*this, r, Range::all()); }
inline Mat Mat::colRange(int startcol, int endcol) const
{ return Mat(*this, Range::all(), Range(startcol, endcol)); }
inline Mat Mat::colRange(const Range& r) const
{ return Mat(*this, Range::all(), r); }