1、稠密数组cv::Mat
cv::Mat构造函数 | 示例 |
---|---|
默认构造函数 | cv::Mat |
构造二维数组 |
cv::Mat(int rows, int cols, int type) cv::Mat(int rows, int cols, int type, const Scalar &s) cv::Mat(int rows, int cols, int type, void *data, size_t step=AUTO_STEP) cv::Mat(cv::Size sz, int type) cv::Mat(cv::Size sz, int type, const Scalar &s) cv::Mat(cv::Size sz, int type, void *data, size_t step=AUTO_STEP)
|
构造多维数组 |
cv::Mat(int ndims, const int *size, int type) cv::Mat(int ndims, const int *size, int type, const Scalar &s) cv::Mat(int ndims, const int *size, int type, void *data, size_t step=AUTO_STEP)
|
复制构造函数 |
cv::Mat(const cv::Mat &mat) cv::Mat(const cv::MatExpr &expr) cv::Mat(const cv::Mat &mat, const cv::Rect &roi) cv::Mat(const cv::Mat &mat, const cv::Range &rows, const cv::Range &cols) cv::Mat(const cv::Mat &mat, const cv::Range *ranges)
|
模板构造函数 |
cv::Mat(const cv::Vec<T,n> &vec, bool coptData=true) cv::Mat(const cv::Matx<T,m,v> &matx, bool copyData=true) cv::Mat(const std::vector<T> &vec, bool copyData=true)
|
静态方法 |
cv::Mat::zeros(int rows, int cols, int type) cv::Mat::ones(int rows, int cols, int type) cv::Mat::eye(int rows, int cols, int type)
|
-
cv::Mat
类可表示矩阵、图像和多维数组,可包含任何原始类型的组合,如数字、向量和其它类型。 -
cv::Mat
的类型:CV_{8U,16S,16U,32S,32F,64F}C{1,2,3}
或者CV_{8U,16S,16U,32S,32F,64F}C({1,2,3,...})
- 对象
cv::Mat
是数据实体的头,其内部的数据指针类似于智能指针,指向数据实体。
Mat m;
m.create(3, 10, CV_32FC3); // 申请内存
m.setTo(Scalar(1.0f, 0.0f, 1.0f)); // 赋值
// 等价于
Mat m(3, 10, CV_32FC3, Scalar(1.0f, 0.0f, 1.0f));
2、访问元素和子区域
访问元素 | 实例 |
---|---|
at<>() |
M.at<int>(i) M.at<int>(pt) M.at<float>(i, j) M.at<float>(i, j, k) M.at<uchar>(idx)
|
ptr<>() |
M.ptr<Vec3f>(i) |
cvMatIterator_<> cvMatConstIterator_<>
|
MatConstIterator_<Vec3f> it = m.begin<Vec3f>() |
cv::NaryMatIterator |
const cv::Mat *arrays[] = {&n_mat, 0} cv::Mat my_planes[1] cv::NAryMatIterator it(arrays, my_planes) it.planes[0]
|
区块访问 | 示例 |
---|---|
row col |
m.row(i) m.col(j)
|
rowRange colRange |
m.rowRange(i0, i1) m.rowRange(cv::Range(i0, i1)) m.colRange(j0, j1) m.colRange(cv::Range(j0, j1))
|
diag | m.diag(d) |
() |
m(cv::Range(i0, i1), cv::Range(j0, j1)) m(cv::Rect(i0, j0, w, h)) m(ranges)
|
- 访问元素的两种方法:通过位置或迭代器访问。位置访问包括
at<>()
和ptr<>()
,其中at<>()
只读。迭代器访问包括cvMatIterator_<>
、cvMatConstIterator_<>
和cv::NaryMatIterator
,其中cvMatConstIterator_<>
只读。 - 数组按行组织,行内按顺序排列,行间因数据对齐可能有间隔。当使用
ptr<>()
遍历数组时需先通过isContinuous()
确定数组行间数据是连续的。 -
cvMatIterator_<>
指向元素,cv::NaryMatIterator
指向一个面(数组中连续内存的片段)。 - 区块访问会创建新的数组头,而不会复制数据,即等号左右两边的变量指向同一内存,修改左边的变量会相应改变右边的变量。
3、矩阵表达式
矩阵表达式支持的运算 | 示例 |
---|---|
矩阵与矩阵的加减 | m0 + m1, m0 - m1 |
矩阵与元素的加减乘 |
m0 + s, m0 - s, s + m0, s - m0 s * m0, m0 * s
|
矩阵元素的乘除 |
m0.mul(m1) m0 / m1
|
矩阵乘法 | m0 * m1 |
点乘和叉乘 | m0.cross(m1), mo.dot(m1) |
取绝对值 | cv::abs(m0) |
取最值 |
min(m0, m1), max(m0, m1) min(m0, s), max(m0, s), min(s, m0), max(s, m0)
|
矩阵比较 | m0 > m1, m0 >= m1, m0==m1, m0 < m1, m0 <= m1 |
逻辑操作 |
m0 & m1, m0 | m1, m0 ^ m1, ~m0 m0 & s, s & m0, m0 | s, s | m0, m0 ^ s, s ^ m0
|
矩阵取负 | -m0 |
逆矩阵 | m0.inv(method) |
转置矩阵 | m0.t() |
静态方法 |
cv::Mat::zeros(rows, cols, type) cv::Mat::ones(rows, cols, type) cv::Mat::eye(rows, cols, type)
|
- OpenCV在进行算术和其它操作时会自动检查是否上溢出和下溢出。
cv::saturate_cast<>()
可在溢出时将结果转换为相对最小或最大的可行值。
4、cv::Mat的其它函数成员
cv::Mat的其它函数成员 | 描述 |
---|---|
m1 = m0.clone() |
对m1重新分配内存并拷贝数据,m1与m0无关 |
m0.copyTo(m1) m0.copyTo(m1, mask)
|
若m0与m1的size、type一致,则只拷贝数据 若不一致则重新分配内存并拷贝数据 若 mask 存在,则只复制mask所指示的区域 |
m0.convertTo(m1, type, scale, offset) |
转换m0中元素的类型(如CV_32F )尺度变换(默认为1) 增加偏置(默认为0) |
m0.assignTo(m1, type) |
只在内部使用,集成在convertTo 中 |
m0.setTo(s, mask) |
设置m0所有元素为s 若 mask 存在,则只对mask 指示区域进行操作 |
m0.reshape(chan, rows) |
改变二维数组的有效形状 若 chan 和rows 为0,则不作修改 |
m0.push_back(s) m0.push_back(m1)
|
在末尾增加m*1大小的数组 在m*n的m0末尾增加k行,m1大小必须是k*n |
m0.pop_back(n) |
从m*n的m0末尾移除n行,默认是1行,返回void类型 |
m0.locateROI(size, offset) |
offset 是Point类型获取 offset 处,大小为size 的ROI。 |
m0.adjustROI(t, b, l, r) |
通过t(above)、b(below)、l(left)、r(reft) 调整ROI范围 |
m0.total() |
计算数组元素的个数(不包括通道) |
m0.isContinuous() |
若m0行间无间隙,则返回true |
m0.elemSize() |
返回m0的位长度,如CV_32FC3 ,(32/8)*3=12 |
m0.elemSize1() |
返回m0最基本元素的位长度,如CV_32FC3 ,32/8=4 |
m0.type() |
返回m0元素的类型,如CV_32FC3
|
m0.depth() |
返回m0通道中元素的类型,如CV_32F
|
m0.channels() |
返回m0的通道数 |
m0.size() |
返回m0的大小size |
m0.size() |
如m0无元素,则返回true,如m0.total==0 或者m.data==NULL
|
5、稀疏数组cv::SparseMat
cv::SparseMat额外的类成员函数 | 示例 |
---|---|
默认构造函数 | cv::SparseMat sm |
值构造函数 | cv::SparseMat sm(3, sz, CV_32F) |
复制构造函数 | cv::SparseMat sm(sm0) |
非0元素的数量 | size_t n = sm.nzcount() |
索引指向的数据的哈希值 |
size_t h = sm.hash(i0) size_t h = sm.hash(i0, i1) size_t h = sm.hash(i0, i1, i3) size_t h = sm.hash(idx)
|
修改元素值 |
sm.ref<float>(i0) = f0 sm.ref<float>(i0, i1) = f0 sm.ref<float>(i0, i1, i2) = f0 sm.ref<float>(idx) = f0
|
获取元素值 |
f0 = sm.value<float>(i0) f0 = sm.value<float>(i0, i1) f0 = sm.value<float>(i0, i1, i2) f0 = sm.value<float>(idx) f0 = sm.find<float>(i0) f0 = sm.find<float>(i0, i1) f0 = sm.find<float>(i0, i1, i2) f0 = sm.find<float>(idx)
|
移除元素 |
sm.erase(i0, i1, &hashval) sm.erase(i0, i1, i2, &hashval) sm.erase(idx, &hashval)
|
迭代器 |
cv::SparseMatIterator<float> it = sm.begin<float>() cv::SparseMatIterator<uchar> it_end = sm.end<float>()
|
-
cv::SparseMat
在数组非0元素非常少时使用,如直方图,高维数组等。 -
cv::Mat
使用接近C风格的数组来存储数据,cv::SparseMat
使用哈希表来存储非0元素。 - 直接访问稀疏数组元素的4种方法:
cv::SparseMat::ptr()
,cv::SparseMat::ref()
,cv::SparseMat::value()
,cv::SparseMat::find()
。其中cv::SparseMat::value()
和cv::SparseMat::find()
只读。 - 迭代器访问稀疏数组的方法:
cv::SparseMatIterator_<>
、cv::SparseMatConstIterator_<>
、cv::SparseMatIterator
、cv::SparseMatConstIterator
。其中cv::SparseMatConstIterator_<>
和cv::SparseMatConstIterator
只读。node()
返回一个指针,指向的稀疏矩阵的实际数据区域。 -
cv::Mat_<>
和cv::SparseMat_<>
是模板,其作用是在使用其成员函数是不用在调用其模板形式。