Mat

OpenCV C++ n-dimensional dense array class

The class Mat represents an n-dimensional dense numerical single-channel or multi-channel array. It can be used to store real or complex-valued vectors and matrices, grayscale or color images, voxel volumes, vector fields, point clouds, tensors, histograms (though, very high-dimensional histograms may be better stored in a SparseMat ).

 

The data layout of the array is defined by the array M.step[], so that the address of element , where , is computed as:

In case of a 2-dimensional array, the above formula is reduced to:

 

Note that M.step[i] >= M.step[i+1] (in fact, M.step[i] >= M.step[i+1]*M.size[i+1] ). This means that 2-dimensional matrices are stored row-by-row, 3-dimensional matrices are stored plane-by-plane, and so on. M.step[M.dims-1] is minimal and always equal to the element size M.elemSize() .

 

There are many different ways to create a Mat object.

Use the create(nrows, ncols, type) method or the similar Mat(nrows, ncols, type[, fillValue]) constructor.

// make a 7x7 complex matrix filled with 1+3j.
Mat M(7,7,CV_32FC2,Scalar(1,3));
// and now turn M to a 100x60 15-channel 8-bit matrix.
// The old content will be deallocated
M.create(100,60,CV_8UC(15));

As noted in the introduction to this chapter, create() allocates only a new array when the shape or type of the current array are different from the specified ones.

Create a multi-dimensional array:

// create a 100x100x100 8-bit array
int sz[] = {100, 100, 100};
Mat bigCube(3, sz, CV_8U, Scalar::all(0));

It passes the number of dimensions =1 to the Mat constructor but the created array will be 2-dimensional with the number of columns set to 1. So, Mat::dims is always >= 2 (can also be 0 when the array is empty).

Construct a header for a part of another array. It can be a single row, single column, several rows, several columns, rectangular region in the array (called a minor in algebra) or a diagonal. Such operations are also O(1) because the new header references the same data. You can actually modify a part of the array using this feature, for example:

// add the 5-th row, multiplied by 3 to the 3rd row
M.row(3) = M.row(3) + M.row(5)*3; // 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(1);
M.col(7).copyTo(M1); // create a new 320x240 image
Mat img(Size(320,240),CV_8UC3);
// select a ROI
Mat roi(img, Rect(10,10,100,100));
// fill the ROI with (0,255,0) (which is green in RGB space);
// the original 320x240 image will be modified
roi = Scalar(0,255,0);

Due to the additional datastart and dataend members, it is possible to compute a relative sub-array position in the main container array using locateROI():

Mat A = Mat::eye(10, 10, CV_32S);
// extracts A columns, 1 (inclusive) to 3 (exclusive).
Mat B = A(Range::all(), Range(1, 3));
// extracts B rows, 5 (inclusive) to 9 (exclusive).
// that is, C ~ A(Range(5, 9), Range(1, 3))
Mat C = B(Range(5, 9), Range::all());
Size size; Point ofs;
C.locateROI(size, ofs);
// size will be (width=10,height=10) and the ofs will be (x=1, y=5)

 

Make a header for user-allocated data. It can be useful to do the following:

Process “foreign” data using OpenCV (for example, when you implement a DirectShow* filter or a processing module for gstreamer, and so on). For example:

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(7,7), 1.5, 1.5);
}

Quickly initialize small matrices and/or get a super-fast element access.

double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}};
Mat M = Mat(3, 3, CV_64F, m).inv();

 

Partial yet very common cases of this user-allocated data case are conversions from CvMat and IplImage to Mat. For this purpose, there are special constructors taking pointers to CvMat or IplImage and the optional flag indicating whether to copy the data or not.

Backward conversion from Mat to CvMat or IplImage is provided via cast operators Mat::operator CvMat()const and Mat::operator IplImage(). The operators do NOT copy the data.

IplImage* img = cvLoadImage("greatwave.jpg", 1);
Mat mtx(img); // convert IplImage* -> Mat
CvMat oldmat = mtx; // convert Mat -> CvMat
CV_Assert(oldmat.cols == img->width && oldmat.rows == img->height &&
oldmat.data.ptr == (uchar*)img->imageData && oldmat.step == img->widthStep);

 

Use MATLAB-style array initializers, zeros(), ones(), eye(), for example:

// create a double-precision identity martix and add it to M.
M += Mat::eye(M.rows, M.cols, CV_64F);

 

 

Use a comma-separated initializer:

// create a 3x3 double-precision identity matrix
Mat M = (Mat_<double>(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);

 

// compute sum of positive matrix elements
// (assuming that M isa double-precision matrix)
double sum=0;
for(int i = 0; i < M.rows; i++)
{
const double* Mi = M.ptr<double>(i);
for(int j = 0; j < M.cols; j++)
sum += std::max(Mi[j], 0.);
}

 

// compute the sum of positive matrix elements, optimized variant
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.);
}

 

// compute sum of positive matrix elements, iterator-based variant
double sum=0;
MatConstIterator_<double> it = M.begin<double>(), it_end = M.end<double>();
for(; it != it_end; ++it)
sum += std::max(*it, 0.);

 

Mat::row

Creates a matrix header for the specified matrix row.

The method makes a new header for the specified matrix row and returns it. This is an O(1) operation, regardless of the matrix size. The underlying data of the new matrix is shared with the original matrix.

Mat::rowRange

Creates a matrix header for the specified row span.

The method makes a new header for the specified row span of the matrix. Similarly to Mat::row() and Mat::col() , this is an O(1) operation.

Mat::copyTo

Copies the matrix to another one.

The method copies the matrix data to another matrix. Before copying the data, the method invokes

m.create(this->size(), this->type());

so that the destination matrix is reallocated if needed. While m.copyTo(m); works flawlessly, the function does not handle the case of a partial overlap between the source and the destination matrices.

When the operation mask is specified, if the Mat::create call shown above reallocates the matrix, the newly allocated matrix is initialized with all zeros before copying the data.

 

 

Mat 类的熟悉程度决定着对OpenCV的操纵能力,必须花时间掌握好~~

OPENCV(2) —— Basic Structures(二)的更多相关文章

  1. OPENCV(2) —— Basic Structures(一)

    DataType A primitive OpenCV data type is one of unsigned char, bool,signed char, unsigned short, sig ...

  2. opencv学习笔记(二)寻找轮廓

    opencv学习笔记(二)寻找轮廓 opencv中使用findContours函数来查找轮廓,这个函数的原型为: void findContours(InputOutputArray image, O ...

  3. HTTP认证之基本认证——Basic(二)

    导航 HTTP认证之基本认证--Basic(一) HTTP认证之基本认证--Basic(二) HTTP认证之摘要认证--Digest(一) HTTP认证之摘要认证--Digest(二) 在HTTP认证 ...

  4. OpenCV中Mat与二维数组之间的转换

    ---恢复内容开始--- 在OpenCV中将Mat(二维)与二维数组相对应,即将Mat中的每个像素值赋给一个二维数组. 全部代码如下: #include <iostream> #inclu ...

  5. 基于Opencv识别,矫正二维码(C++)

    参考链接 [ 基于opencv 识别.定位二维码 (c++版) ](https://www.cnblogs.com/yuanchenhui/p/opencv_qr.html) OpenCV4.0.0二 ...

  6. OpenCV使用FindContours进行二维码定位

    我使用过FindContours,而且知道有能够直接寻找联通区域的函数.但是我使用的大多只是"最大轮廓"或者"轮廓数目"这些数据.其实轮廓还有另一个很重要的性质 ...

  7. opencv探索之路(十二):感兴趣区域ROI和logo添加技术

    在图像处理领域,有一个非常重要的名词ROI. 什么是ROI? 它的英文全称是Region Of Interest,对应的中文解释就是感兴趣区域. 感兴趣区域,就是我们从图像中选择一个图像区域,这个区域 ...

  8. Python+OpenCV图像处理(十二)—— 图像梯度

    简介:图像梯度可以把图像看成二维离散函数,图像梯度其实就是这个二维离散函数的求导. Sobel算子是普通一阶差分,是基于寻找梯度强度.拉普拉斯算子(二阶差分)是基于过零点检测.通过计算梯度,设置阀值, ...

  9. Python下opencv使用笔记(二)(简单几何图像绘制)

    简单几何图像一般包含点.直线.矩阵.圆.椭圆.多边形等等.首先认识一下opencv对像素点的定义. 图像的一个像素点有1或者3个值.对灰度图像有一个灰度值,对彩色图像有3个值组成一个像素值.他们表现出 ...

随机推荐

  1. ETL工具-informatica产品部分功能、接口采购梳理

    在项目中,经常遇到要进行产品采购,虽然一直在使用informatica工具做数据的抽取.清晰转换.加载,但是使用的功能也比较初级.在遇到采购时大致的进行了梳理. 序号 名称 产品功能说明 产品选配说明 ...

  2. Docker和虚拟机的区别

    这是docker官网的图,可以看到虚拟化技术通过Hypervisor(虚拟机管理系统)为每个app启动一个Guest OS(客户机操作系统),也就是为每个app启动一个虚拟机.比较直观地说,vm通过H ...

  3. Axure7.0在OS X Yosemite(10.10)中不能用的问题

    电脑升级到了10.10后发现axure7.0不能使用.解决办法也非常easy,就是又一次下载一个新的axure版本号,下载地址:http://www.axure.com/release-candida ...

  4. 第十六周项目3:max带来的冲突

    问题及代码: /* *Copyright (c)2015,烟台大学计算机与控制工程学院 *All rights reserved. *文件名:project.cpp *作 者:陈文青 *完毕日期:20 ...

  5. vncserverpassword改动

    前几天去客户现场,客户说有測试库.Linux下的,帮忙给新建一个数据库,我这么热心的人.是吧 那就開始吧. 一般使用vnc搞图形安装.熟练的打开vnc.输入password,报错!!我愣了几秒,忽然反 ...

  6. 使用quick自己定义Button

    使用quick时自己封装的类存放于特定的文件夹.便于以后使用 以下是作者经经常使用到的一个按钮 local MyButton = class("MyButton") functio ...

  7. Android之输入内容监听回车键【Editor】

    2.输入内容时按下回车键时监听 username.setOnEditorActionListener(new OnEditorActionListener() { @Override public b ...

  8. xp秘钥

    TDCXC-M9FW9-3HQ28-CPXYR-YXQ3QCCBDF-9W9T8-K8B7M-83HJM-X2MCWP3MF6-BTDKT-KR7YF-X4BM9-4HD9TMCCWF-42JGF-W ...

  9. [COI2007] [luogu P1823] Patrik 音乐会的等待 解题报告 (单调栈)

    题目链接:https://www.luogu.org/problemnew/show/P1823 题目: N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人. ...

  10. 16.允许重复的multimap

    #include <iostream> #include <map> #include <cstring> using namespace std; void ma ...