OpenCV学习(5) Mat的基本操作(2)
本章我们学习一下Mat中的常用操作,因为在后面其它的教程中,我们经常要对图像进行各种处理,也要使用这些操作。
一、 Mat的复制,就是从一个矩阵A,生成相关的另一个矩阵B。
(1)使用赋值的方法,比如通过构造函数生成矩阵N,通过复制生成矩阵P
cv::Mat N(M);
cv::Mat P;
P=M;
这样生成的矩阵,只是新生成一个矩阵头,它的data依然指向矩阵M的data,类似C++中的浅拷贝,比如矩阵M,N,P它们的data都指向地址0x00badd50



(2) 使用copyTo和clone函数
cv::Mat F = M.clone();
cv::Mat G;
F.copyTo(G);
这样可以生成一个全新的矩阵,不但复制矩阵的头信息,而且会生成一个data的拷贝。比如矩阵F和M,它们的data指针地址和F是不同的。


注意:copyTo函数,它还可以带有掩码矩阵copyTo(G, maskImage), maskImage是一个单通道的矩阵,值为0的位置,在拷贝时候并不会拷贝。

二、Mat中常用的几个函数
1. convertTo(OutputArray m, int rtype, double alpha=1, double beta=0 )
生成一个新矩阵,矩阵的中值为原矩阵中的值乘以alpha,然后再加上beta

imageMask.convertTo(mark1,CV_8U);
2. Mat::reshape(int cn),改变矩阵的维数,比如把二维矩阵改变成一维矩阵。这个操作只是改变矩阵的头信息,比如在没有padding数据情况下,便于数据处理,有时候我们会把二维矩阵变成一维矩阵。
imageMask.reshape(1);
3. isContinous,检测矩阵是否有padding数据。
double sum=0;
int cols = M.cols, rows = M.rows;
if(M.isContinuous())
{
cols *= rows;
rows = 1;
}
for(int i = 0; i < rows; i++)
{
const double* Mi = M.ptr<double>(i);
for(int j = 0; j < cols; j++)
sum += std::max(Mi[j], 0.0);
}
4. 用下面的代码,可以取出矩阵的某个ROI区域,以便进行处理。
cv::Rect rect(100, 100, 100, 100);
srcImage(rect).copyTo(roiImage);
5.下面的代码,实现一个矩阵的子矩阵赋值,矩阵roi的data指针会指向result1的data的50行,70列处。
cv::Mat result1= cv::Mat(image1.rows, image1.cols,CV_8UC1, cv::Scalar(cv::GC_BGD));
//注意给子矩阵赋值的方法
cv::Mat roi(result1, cv::Rect(50,70,result1.cols-150,result.rows-180));
roi = cv::Scalar(cv::GC_PR_FGD);
三、简单的三维矩阵示例
//创建一个3维矩阵,每维都是长度为2
int sz[3] = {3,3,3};
cv::Mat L(3,sz, CV_8UC(1), cv::Scalar::all(1));
//打印多维数组
for(i=0; i< 3; i++)
{
for(j=0; j<3; j++)
{
for(k=0; k<3; k++)
{
// printf("%d \n", L.data[i*3*3 + j*3 +k]);
}
}
}
四、稀疏矩阵
有时候,我们需要使用多维矩阵存储一些值,比如三维BGR图像的直方图,由于每维的索引数都是256,所以矩阵元素数量达到256*256*256,如果用普通矩阵存储,需要分配很大的空间,这时候,最好使用稀疏矩阵sparseMat,因为在稀疏矩阵中只保存非零的值。
下面是使用稀疏矩阵的简单例子:
//稀疏矩阵的操作
//创建一个三维的稀疏矩阵
const int dims = 3;
int size[] = {256, 256, 256};
SparseMat sparse_mat(dims, size, CV_32F);
//20个非0的值,注意:稀疏矩阵保存非零的值
for(int i = 0; i < 20; i++)
{
int idx[dims];
for(int k = 0; k < dims; k++)
idx[k] = rand()%256;
sparse_mat.ref<float>(idx) = 2.f;
}
//显示稀疏矩阵的结果
SparseMatConstIterator_<float> it1 = sparse_mat.begin<float>(), it_end = sparse_mat.end<float>();
double s = 0;
int dims1 = sparse_mat.dims();
for(; it1 != it_end; ++it1)
{
// 打印索引和元素的值
const SparseMat::Node* n = it1.node();
printf("(");
for(int i = 0; i < dims1; i++)
printf("%d%s", n->idx[i], i < dims-1 ? ", " : ")");
printf(": %g\n", it1.value<float>());
s += *it1;
}
printf("元素的个数 %g\n", s);
程序运行的结果:

源文件:工程FirstOpenCV2。
OpenCV学习(5) Mat的基本操作(2)的更多相关文章
- OpenCV学习(4) Mat的基本操作(1)
图像在OpenCV中都是通过Mat类来存储的,Mat可以用来表示N维矩阵,当然用的最多的还是二维矩阵. Mat类有两部分组成:第一部分是头信息,这些信息主要用来描述矩阵,比如矩 ...
- OpenCV学习:Mat结构中的数据共享机制
使用Mat类,内存管理变得简单,不再像使用IplImage那样需要自己申请和释放内存. Mat是一个类,由两个数据部分组成:矩阵头(包含矩阵尺寸,存储方法,存储地址等信息)和一个指向存储所有像素值的矩 ...
- OpenCV学习笔记——Mat类型数据存储
CV_[The number of bits per item][Signed or Unsigned][Type Prefix]C[The channel number] 比如 CV_8UC3 表示 ...
- OpenCV学习(3)--Mat矩阵的操作
CvMat的矩阵结构 typedef struct CvMat { //矩阵中元素的类型 int type; //行数据长度 int step; /* for internal use only */ ...
- opencv学习笔记(一)IplImage, CvMat, Mat 的关系
opencv学习笔记(一)IplImage, CvMat, Mat 的关系 opencv中常见的与图像操作有关的数据容器有Mat,cvMat和IplImage,这三种类型都可以代表和显示图像,但是,M ...
- [OpenCV学习笔记2][Mat数据类型和操作]
[Mat数据类型和基本操作] ®.运行环境:Linux(RedHat+OpenCV3.0) 1.Mat的作用: Mat类用于表示一个多维的单通道或者多通道的稠密数组.能够用来保存实数或复数的向量.矩阵 ...
- OpenCV学习C++接口 Mat像素遍历详解
OpenCV学习C++接口 Mat像素遍历详解
- opencv学习笔记(六)直方图比较图片相似度
opencv学习笔记(六)直方图比较图片相似度 opencv提供了API来比较图片的相似程度,使我们很简单的就能对2个图片进行比较,这就是直方图的比较,直方图英文是histogram, 原理就是就是将 ...
- opencv学习笔记(五)镜像对称
opencv学习笔记(五)镜像对称 设图像的宽度为width,长度为height.(x,y)为变换后的坐标,(x0,y0)为原图像的坐标. 水平镜像变换: 代码实现: #include <ios ...
随机推荐
- js中post中文参数转码和解码
作为基础知识和血淋林的教训,前端一定要记得post请求时将参数中带有中文的部分进行转码!! var str='宋宇·特弱夫斯基'; //转码: encodeURI(encodeURI(str)) ; ...
- lr的脚本调试方法
1) 设置调试断点(快捷键F9)当设置断点的脚本,脚本运行到断点处,自动停止运行,我们可以通过查看运行日志,来观察脚本执行的情况: LR中也能设置断点,具体菜单在:Insert - Toggle B ...
- Django实现单用户登录
最近由于要毕业了写论文做毕设,然后还在实习发现已经好久都没有写博客了.今天由于工作需求,需要用Django实现单用户登录.大概意思就是跟QQ一样的效果,每个账号只能一个地方登录使用,限制账号的登录次数 ...
- 为什么ArrayList remove报错
不报错 List<String> userNames = new ArrayList<String>() {{ add("Hollis"); add(&qu ...
- Contains,Exists,Any,Count 比较是否存在某个元素
private static void Main(string[] args) { ; Console.WriteLine("判断是否存在某个元素 :"); Console.Wri ...
- openvpn部署centos7
[root@openvpn ~]# cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core) 安装包 yum upgrade yum i ...
- BZOJ1073 k短路(A*算法)
A*算法,也叫启发式搜索,就是设计一个预估函数,然后在搜索的过程中进行有序的搜索,我们设到目前状态的花费为f(x),到目标状态的估计花费为h(x),那么我们按照h(x)+f(x)排序即可,这道题里起点 ...
- [BZOJ4311]向量(凸包+三分+线段树分治)
可以发现答案一定在所有向量终点形成的上凸壳上,于是在上凸壳上三分即可. 对于删除操作,相当于每个向量有一个作用区间,线段树分治即可.$O(n\log^2 n)$ 同时可以发现,当询问按斜率排序后,每个 ...
- [BZOJ4028][HEOI2015]公约数数列(分块)
先发掘性质: 1.xor和gcd均满足交换律与结合率. 2.前缀gcd最多只有O(log)个. 但并没有什么数据结构能同时利用这两个性质,结合Q=10000,考虑分块. 对每块记录这几个信息: 1.块 ...
- [P3759][TJOI2017]不勤劳的图书管理员(分块+树状数组)
题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生 这两本书页数的和的厌烦度.现在有n本被打乱顺序的书 ...