[OpenCV]Mat类详解
http://blog.csdn.net/yang_xian521/article/details/7107786
Preface
Mat:Matrix
Mat类可以被看做是opencv中C++版本的矩阵类,通俗的说就是操作矩阵(例如:求逆/转置/加减乘除等等,), 而图片的存储就是矩阵,所以经常用他来处理图片
Mat最大的优势跟STL很相似,有很多类似于STL的操作。但是Mat远远强于后者;二者都是对内存进行动态的管理,不需要之前用户手动的管理内存
Mat类的存储和数据类型
Mat的存储是逐行的存储的
• CV_8U - 8-bit unsigned integers ( 0..255 ) • CV_8S - 8-bit signed integers ( -128..127 ) • CV_16U - 16-bit unsigned integers ( 0..65535 ) • CV_16S - 16-bit signed integers ( -32768..32767 ) • CV_32S - 32-bit signed integers ( -2147483648..2147483647 ) • CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN ) • CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )
创建Mat类的对象
Mat这个类有两部分数据。
一个是矩阵头(matrix header),这部分大小固定,包含矩阵的大小,存储的方式,矩阵存储的地址等等。
另一个部分是一个指针: 指向矩阵所包含的像素数据
// make a 7x7 complex matrix filled with 1+3j.
Mat M(,,CV_32FC2,Scalar(,));
// and now turn M to a 100x60 15-channel 8-bit matrix.
// The old content will be deallocated
M.create(,,CV_8UC());
创建一个M矩阵,7行7列,类型为CV_32F,C2表示有2个通道。Scalar(1,3)是对矩阵进行初始化赋值。第一个通道全为1,第2个通道全为3。具体见一下:
scalar是将图像设置成单一灰度和颜色,怪不得叫scalar(标量/纯量)。
Mat rawImg(, , CV_8UC3, Scalar(, , ));
运行结果:

Mat类的矩阵操作
Row 行 Column列操作
// add the 5-th row, multiplied by 3 to the 3rd row
M.row() = M.row() + M.row()*;
// now copy the 7-th column to the 1-st column
// M.col(1) = M.col(7); // this will not work
Mat M1 = M.col();
M.col().copyTo(M1);
注意对列操作时要新建一个Mat,我想应该跟列地址不连续有关
接收指针指向的数据流
对于外来的数据,比如你从别的地方接受了一幅图片,但可以不是Mat结构的,而只有一个数据的指针,看看接下来的代码是如何应付的,
void process_video_frame(const unsigned char* pixels,int width, int height, int step)
{
Mat img(height, width, CV_8UC3, pixels, step);
GaussianBlur(img, img, Size(,), 1.5, 1.5);
}
快速初始化数据
double m[][] = {{a, b, c}, {d, e, f}, {g, h, i}};
Mat M = Mat(, , CV_64F, m).inv();
也可以把原来的IplImage格式的图片直接用Mat(IplImage)的方式转成Mat结构,
也可以像Matlab一样调用zeros()、ones()、eye()这样的函数进行初始化。
内存释放
如果你需要提前释放数据的指针和内存,可以调用release()。
数据的获取
调用at<float>(3, 3)这样的格式为最佳
需要注意的问题:
1 很多OpenCV的函数支持的数据深度只有8位和32位的,所以要少使用CV_64F,但是vs的编译器又会把float数据自动变成double型,有些不太爽。
2 流操作符<<对于Mat的操作,仅限于Mat是2维的情况。
3
Mat A, C; // creates just the header parts
A = imread(argv[], CV_LOAD_IMAGE_COLOR); // here we’ll know the method used (allocate matrix)
Mat B(A); // Use the copy constructor
C = A; // Assignment operator
需要注意的是,copy这样的操作只是copy了矩阵的matrix header和那个指针,而不是矩阵的本身,也就意味着两个矩阵的数据指针指向的是同一个地址,需要开发者格外注意。
比如上面这段程序,A、B、C指向的是同一块数据,他们的header不同,但对于A的操作同样也影响着B、C的结果。
刚刚提到了内存自动释放的问题,那么当我不再使用A的时候就把内存释放了,那时候再操作B和C岂不是很危险?
不用担心,OpenCV的大神为我们已经考虑了这个问题,是在最后一个Mat不再使用的时候才会释放内存,咱们就放心用就行了。
如果想建立互不影响的Mat,是真正的复制操作,需要使用函数clone()或者copyTo()。
[OpenCV]Mat类详解的更多相关文章
- OpenCV参考手册之Mat类详解
OpenCV参考手册之Mat类详解(一) OpenCV参考手册之Mat类详解(二) OpenCV参考手册之Mat类详解(三)
- OPENCV mat类
OpenCV参考手册之Mat类详解 目标 我们有多种方法可以获得从现实世界的数字图像:数码相机.扫描仪.计算机体层摄影或磁共振成像就是其中的几种.在每种情况下我们(人类)看到了什么是图像.但是,转换图 ...
- Mat的详解
[转]OpenCV中Mat的详解 每次碰到Mat都得反复查具体的用法,网上的基础讲解不多,难得看到一篇,赶快转来收藏~ 原文地址:http://www.opencvchina.com/thread-1 ...
- java之StringBuffer类详解
StringBuffer 线程安全的可变字符序列. StringBuffer源码分析(JDK1.6): public final class StringBuffer extends Abstract ...
- java之AbstractStringBuilder类详解
目录 AbstractStringBuilder类 字段 构造器 方法 public abstract String toString() 扩充容量 void expandCapacity(in ...
- java之StringBuilder类详解
StringBuilder 非线程安全的可变字符序列 .该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍).如果可能,建议优先采用该类,因为在 ...
- Java String类详解
Java String类详解 Java字符串类(java.lang.String)是Java中使用最多的类,也是最为特殊的一个类,很多时候,我们对它既熟悉又陌生. 类结构: public final ...
- QAction类详解:
先贴一段描述:Qt文档原文: Detailed Description The QAction class provides an abstract user interface action tha ...
- JAVAEE学习——struts2_01:简介、搭建、架构、配置、action类详解和练习:客户列表
一.struts2是什么 1.概念 2.struts2使用优势以及历史 二.搭建struts2框架 1.导包 (解压缩)struts2-blank.war就会看到 2.书写Action类 public ...
随机推荐
- 昂贵的聘礼,(最短路的应用),Poj(1063)
题目链接:http://poj.org/problem?id=1062 很好的一道中文题. 思路: 把每种替换当做一条边,权重为交易优惠,就是求原点0到物品1的最短路. 这里有限制条件,每个节点还有等 ...
- GNOME keyring [(null)] 的密码:
在ubuntu下执行svn checkout命令时,总是报下面的错误: GNOME keyring [(null)] 的密码:svn: 方法 OPTIONS 失败于 “http://xxxxxxxx/ ...
- 【Java-Method】读《重构》有感_Java方法到底是传值调用还是传引用调用(传钥匙调用)
今天读<重构>P279, Separate Query from Modifier,将查询函数和修改函数分离. 问题的产生 突然想到 Java 的传对象作为参数的方法到底是 传引用调用,还 ...
- sudo 密码超时时间
Centos 没有默认超时时间,所以用一次sudo就需要输入密码. vi /etc/sudoers 添加下面的内容,2表示分钟数(看自己需求更改). Defaults timestamp_timeou ...
- c++谭浩强教材教学练习例题1.2 求两数之和 为什么sum=a+b;sum的值为65538
第一章 #include <iostream>using namespace std; int main(){ int a,b,sum; sum=a+b; cin>>a> ...
- Java的按值传递和按引用传递解说
在网上看到的一个帖子解释Java的按值传递和按引用传递,感觉挺全面,就转过来,以供以后学习参考: 1:按值传递是什么 指的是在方法调用时,传递的参数是按值的拷贝传递.示例如下: public clas ...
- 自定义扩展Compare比较方法
public static int Compare<T, V>(this T x, T y, Func<T, V> func) { return Comparer<V&g ...
- GNU 关闭 MMU 和 Icache 和 Dcache
1. cp15 寄存器 disable Icache 和 Dcache . disable_MMU: MCR p15,0,r0,c7,c7,0 MRC p15,0,r0,c1,c0,0 bic r ...
- angular常见问题总结
本文引自:https://www.cnblogs.com/zhoulujun/p/8881414.html 这篇是对angularJS的一些疑点回顾,是对目前angularJS开发的各种常见问题的整理 ...
- RocketMQ源码分析之RocketMQ事务消息实现原理中篇----事务消息状态回查
上节已经梳理了RocketMQ发送事务消息的流程(基于二阶段提交),本节将继续深入学习事务状态消息回查,我们知道,第一次提交到消息服务器时消息的主题被替换为RMQ_SYS_TRANS_HALF_TOP ...