本章我们学习一下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)的更多相关文章

  1. OpenCV学习(4) Mat的基本操作(1)

          图像在OpenCV中都是通过Mat类来存储的,Mat可以用来表示N维矩阵,当然用的最多的还是二维矩阵.       Mat类有两部分组成:第一部分是头信息,这些信息主要用来描述矩阵,比如矩 ...

  2. OpenCV学习:Mat结构中的数据共享机制

    使用Mat类,内存管理变得简单,不再像使用IplImage那样需要自己申请和释放内存. Mat是一个类,由两个数据部分组成:矩阵头(包含矩阵尺寸,存储方法,存储地址等信息)和一个指向存储所有像素值的矩 ...

  3. OpenCV学习笔记——Mat类型数据存储

    CV_[The number of bits per item][Signed or Unsigned][Type Prefix]C[The channel number] 比如 CV_8UC3 表示 ...

  4. OpenCV学习(3)--Mat矩阵的操作

    CvMat的矩阵结构 typedef struct CvMat { //矩阵中元素的类型 int type; //行数据长度 int step; /* for internal use only */ ...

  5. opencv学习笔记(一)IplImage, CvMat, Mat 的关系

    opencv学习笔记(一)IplImage, CvMat, Mat 的关系 opencv中常见的与图像操作有关的数据容器有Mat,cvMat和IplImage,这三种类型都可以代表和显示图像,但是,M ...

  6. [OpenCV学习笔记2][Mat数据类型和操作]

    [Mat数据类型和基本操作] ®.运行环境:Linux(RedHat+OpenCV3.0) 1.Mat的作用: Mat类用于表示一个多维的单通道或者多通道的稠密数组.能够用来保存实数或复数的向量.矩阵 ...

  7. OpenCV学习C++接口 Mat像素遍历详解

    OpenCV学习C++接口 Mat像素遍历详解

  8. opencv学习笔记(六)直方图比较图片相似度

    opencv学习笔记(六)直方图比较图片相似度 opencv提供了API来比较图片的相似程度,使我们很简单的就能对2个图片进行比较,这就是直方图的比较,直方图英文是histogram, 原理就是就是将 ...

  9. opencv学习笔记(五)镜像对称

    opencv学习笔记(五)镜像对称 设图像的宽度为width,长度为height.(x,y)为变换后的坐标,(x0,y0)为原图像的坐标. 水平镜像变换: 代码实现: #include <ios ...

随机推荐

  1. QString 与中文问题

    原文请看:http://www.cnblogs.com/phoenixlaozhu/articles/2553180.html (更新:本文的姊妹篇Qt5与中文问题) 首先呢,声明一下,QString ...

  2. Python导入模块-Import

    #1语法importimport module1,module2,module3,module4 #2from xx import xx 语句from module import name1,name ...

  3. Java synchronized的原理解析

    开始 类有一个特性叫封装,如果一个类,所有的field都是private的,而且没有任何的method,那么这个类就像是四面围墙+天罗地网,没有门.看起来就是一个封闭的箱子,外面的进不来,里面的出不去 ...

  4. 对java前后端分离的理解

    到目前为止,身为一个java后端开发人员的我, 在工作期间,无非就是ui设计页面,前端开发html,之后将做好的页面交给我,我负责后台逻辑一件html的页面渲染. 好好滴一个后台开发人员,莫名其妙的做 ...

  5. PBR Step by Step(一)立体角

    转载请注明出处:http://www.cnblogs.com/jerrycg/p/4924761.html  本系列从零起步,作为学习笔记与大家分享,从基础的数学和图形理论,一步一步实现基于物理的渲染 ...

  6. 为什么我喜欢Java

    我现在的老板使用一个在线测试系统来筛选在线申请职位的求职者.测试的第一个问题很浅显,仅仅是为了让求职者熟悉一下这个系统的提交和测试代码的流程.问题是这样的,写一个将标准输入拷贝到标准输出的流程.求职者 ...

  7. [GCJ2017R3]Cooclement

    题目大意: 一种数列按照如下方式变化: 新数列第i位等于原数中数字i的出现次数. 变化过程中数列长度不变. 例如数列12的变化过程为12-11-20-01-10. 现在告诉你一个数列x,请求出x可能是 ...

  8. cordova安卓手机<a href="tel:xxx"></a>无法进入拨号界面问题

    在使用cordova开发跨平台APP时,可能会用到点击某个按钮进入拨号界面的问题,HTML中的a标签提供了这个功能,但在部分安卓手机中却没有作用,点击没有反应,解决的方法如下:(在config.xml ...

  9. zoj 1610 Count the Colors 线段树区间更新/暴力

    Count the Colors Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/show ...

  10. 使用辗转相除法求两个数的最大公因数(python实现)

    数学背景: 整除的定义: 任给两个整数a,b,其中b≠0,如果存在一个整数q使得等式                                        a = bq 成立,我们就说是b整除 ...