学习OpenCV3: 第4章 图像和大型数组类型


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)
  1. cv::Mat类可表示矩阵、图像和多维数组,可包含任何原始类型的组合,如数字、向量和其它类型。
  2. cv::Mat的类型:CV_{8U,16S,16U,32S,32F,64F}C{1,2,3}或者CV_{8U,16S,16U,32S,32F,64F}C({1,2,3,...})
  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)
  1. 访问元素的两种方法:通过位置或迭代器访问。位置访问包括at<>()ptr<>(),其中at<>()只读。迭代器访问包括cvMatIterator_<>cvMatConstIterator_<>cv::NaryMatIterator,其中cvMatConstIterator_<>只读。
  2. 数组按行组织,行内按顺序排列,行间因数据对齐可能有间隔。当使用ptr<>()遍历数组时需先通过isContinuous()确定数组行间数据是连续的。
  3. cvMatIterator_<>指向元素,cv::NaryMatIterator指向一个面(数组中连续内存的片段)。
  4. 区块访问会创建新的数组头,而不会复制数据,即等号左右两边的变量指向同一内存,修改左边的变量会相应改变右边的变量。

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)
  1. 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) 改变二维数组的有效形状
chanrows为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>()
  1. cv::SparseMat在数组非0元素非常少时使用,如直方图,高维数组等。
  2. cv::Mat使用接近C风格的数组来存储数据,cv::SparseMat使用哈希表来存储非0元素。
  3. 直接访问稀疏数组元素的4种方法:cv::SparseMat::ptr()cv::SparseMat::ref()cv::SparseMat::value()cv::SparseMat::find()。其中cv::SparseMat::value()cv::SparseMat::find()只读。
  4. 迭代器访问稀疏数组的方法:cv::SparseMatIterator_<>cv::SparseMatConstIterator_<>cv::SparseMatIteratorcv::SparseMatConstIterator。其中cv::SparseMatConstIterator_<>cv::SparseMatConstIterator只读。node()返回一个指针,指向的稀疏矩阵的实际数据区域。
  5. cv::Mat_<>cv::SparseMat_<>是模板,其作用是在使用其成员函数是不用在调用其模板形式。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342