OpenCV Mat 简介
OpenCV Mat 简介
Part I
Mat是OpenCV最基本的数据结构,Mat即矩阵(Matrix)的缩写,Mat数据结构主要包含2部分:Header和Pointer。Header中主要包含矩阵的大小,存储方式,存储地址等信息;Pointer中存储指向像素值的指针。我们在读取图片的时候就是将图片定义为Mat类型,其重载的构造函数一大堆,
class CV_EXPORTS Mat { public://! default constructorMat();//! constructs 2D matrix of the specified size and type// (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)Mat(int _rows, int _cols, int _type);Mat(Size _size, int _type);//! constucts 2D matrix and fills it with the specified value _s.Mat(int _rows, int _cols, int _type, const Scalar& _s);Mat(Size _size, int _type, const Scalar& _s);//! constructs n-dimensional matrixMat(int _ndims, const int* _sizes, int _type);Mat(int _ndims, const int* _sizes, int _type, const Scalar& _s);//! copy constructorMat(const Mat& m);//! constructor for matrix headers pointing to user-allocated dataMat(int _rows, int _cols, int _type, void* _data, size_t _step=AUTO_STEP);Mat(Size _size, int _type, void* _data, size_t _step=AUTO_STEP);Mat(int _ndims, const int* _sizes, int _type, void* _data, const size_t* _steps=0);//! creates a matrix header for a part of the bigger matrixMat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all());Mat(const Mat& m, const Rect& roi);Mat(const Mat& m, const Range* ranges);//! converts old-style CvMat to the new matrix; the data is not copied by defaultMat(const CvMat* m, bool copyData=false);//! converts old-style CvMatND to the new matrix; the data is not copied by defaultMat(const CvMatND* m, bool copyData=false);//! converts old-style IplImage to the new matrix; the data is not copied by defaultMat(const IplImage* img, bool copyData=false);......}
要了解如何初始化Mat结构,就应该了解它的构造函数,比如程序中的第一初始化方式调用额就是
Mat(int _rows, int _cols, int _type, const Scalar& _s);
这个构造函数。
IplImage*是C语言操作OpenCV的数据结构,在当时C操纵OpenCV的时候,地位等同于Mat,OpenCV为其提供了一个接口,很方便的直接将IplImage转化为Mat,即使用构造函数
Mat(const IplImage* img, bool copyData=false);
上面程序中的第二种方法就是使用的这个构造函数。
关于Mat数据复制:前面说过Mat包括头和数据指针,当使用Mat的构造函数初始化的时候,会将头和数据指针复制(注意:只是指针复制,指针指向的地址不会复制),若要将数据也复制,则必须使用copyTo或clone函数
Mat还有几个常用的成员函数,在之后的文章中将会使用到:
//! returns true iff the matrix data is continuous // (i.e. when there are no gaps between successive rows). // similar to CV_IS_MAT_CONT(cvmat->type) bool isContinuous() const;
这了解上面的函数作用前,得了解下OpenCV中存储像素的方法,如下,灰度图(单通道)存储按行列存储,
三通道RGB存储方式如下,每列含有三个通道,
为了加快访问的速度,openCV往往会在内存中将像素数据连续地存储成一行,isContinus()函数的作用就是用于判断是否连续存储成一行。存储成一行有什么好处呢?给定这行的头指针p,则只要使用p++操作就能逐个访问数据。
因此当判断存放在一行的时候,可以通过数据指针++很容易遍历图像像素:
long nRows = M.rows * M.channels(); // channels()也是Mat中一个常用的函数,用于获取通道数(RGB=3,灰度=1) long nCols = M.cols; uchar *p = M.data; // 数据指针 if(M.isContinuous()) {nCols *= nRows;for (long i=0; i < nCols; i++) {*p++ = ...; // 像素赋值或读取操作} }
请注意以上几个常用的Mat成员遍历和函数:
M.row; // 返回图像行数 M.nCols; // 返回图像列数 M.channels(); //返回通道数 M.isContinuous(); // 返回bool类型表示是否连续存储
程序示例
/* * FileName : MatObj.cpp * Author : xiahouzuoxin @163.com * Version : v1.0 * Date : Thu 15 May 2014 09:12:45 PM CST * Brief : * * Copyright (C) MICL,USTB */ #include <cv.h> #include <highgui.h> #include <iostream>using namespace std; using namespace cv;int main(void) {/* * Create Mat */Mat M(2,2,CV_8UC3, Scalar(0,0,255));cout << "M=" << endl << " " << M << endl << endl;/* * Matlab style */Mat E = Mat::eye(4,4,CV_64F);cout << "E=" << endl << " " << E << endl << endl;E = Mat::ones(4,4,CV_64F);cout << "E=" << endl << " " << E << endl << endl;E = Mat::zeros(4,4,CV_64F);cout << "E=" << endl << " " << E << endl << endl;/* * Convert IplImage to Mat */IplImage *img = cvLoadImage("../test_imgs/Lena.jpg");Mat L(img);namedWindow("Lena.jpg", CV_WINDOW_AUTOSIZE); imshow("Lena.jpg", L);waitKey(0);/* * Init Mat with separated data */Mat C = (Mat_<int>(3,3) << 0,1,2,3,4,5,6,7,8);cout << "C=" << endl << " " << C << endl << endl;return 0; }
左边是矩阵的一些操作输出结果,右边的图是通过IplImage *结构读入,转换为Mat后显示结果。
Part II
Mat的作用
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 ).
上面的一段话引用自官方的文档,Mat类用于表示一个多维的单通道或者多通道的稠密数组。能够用来保存实数或复数的向量、矩阵,灰度或彩色图像,立体元素,点云,张量以及直方图(高维的直方图使用SparseMat保存比较好)。简而言之,Mat就是用来保存多维的矩阵的。
Mat的常见属性
- data uchar型的指针。Mat类分为了两个部分:矩阵头和指向矩阵数据部分的指针,data就是指向矩阵数据的指针。
- dims 矩阵的维度,例如5*6矩阵是二维矩阵,则dims=2,三维矩阵dims=3.
- rows 矩阵的行数
- cols 矩阵的列数
- size 矩阵的大小,size(cols,rows),如果矩阵的维数大于2,则是size(-1,-1)
- channels 矩阵元素拥有的通道数,例如常见的彩色图像,每一个像素由RGB三部分组成,则channels = 3
下面的几个属性是和Mat中元素的数据类型相关的。
- type
表示了矩阵中元素的类型以及矩阵的通道个数,它是一系列的预定义的常量,其命名规则为CV_(位数)+(数据类型)+(通道数)。具体的有以下值:CV_8UC1 CV_8UC2 CV_8UC3 CV_8UC4 CV_8SC1 CV_8SC2 CV_8SC3 CV_8SC4 CV_16UC1 CV_16UC2 CV_16UC3 CV_16UC4 CV_16SC1 CV_16SC2 CV_16SC3 CV_16SC4 CV_32SC1 CV_32SC2 CV_32SC3 CV_32SC4 CV_32FC1 CV_32FC2 CV_32FC3 CV_32FC4 CV_64FC1 CV_64FC2 CV_64FC3 CV_64FC4 这里U(unsigned integer)表示的是无符号整数,S(signed integer)是有符号整数,F(float)是浮点数。
例如:CV_16UC2,表示的是元素类型是一个16位的无符号整数,通道为2.
C1,C2,C3,C4则表示通道是1,2,3,4
type一般是在创建Mat对象时设定,如果要取得Mat的元素类型,则无需使用type,使用下面的depth - depth
矩阵中元素的一个通道的数据类型,这个值和type是相关的。例如 type为 CV_16SC2,一个2通道的16位的有符号整数。那么,depth则是CV_16S。depth也是一系列的预定义值,
将type的预定义值去掉通道信息就是depth值:
CV_8U CV_8S CV_16U CV_16S CV_32S CV_32F CV_64F - elemSize
矩阵一个元素占用的字节数,例如:type是CV_16SC3,那么elemSize = 3 * 16 / 8 = 6 bytes - elemSize1
矩阵元素一个通道占用的字节数,例如:type是CV_16CS3,那么elemSize1 = 16 / 8 = 2 bytes = elemSize / channels
下面是一个示例程序,具体说明Mat的各个属性:
Mat img(3, 4, CV_16UC4, Scalar_<uchar>(1, 2, 3, 4));cout << img << endl;cout << "dims:" << img.dims << endl;cout << "rows:" << img.rows << endl;cout << "cols:" << img.cols << endl;cout << "channels:" << img.channels() << endl;cout << "type:" << img.type() << endl;cout << "depth:" << img.depth() << endl;cout << "elemSize:" << img.elemSize() << endl;cout << "elemSize1:" << img.elemSize1() << endl;
首先创建了一个3*4的具有4个通道的矩阵,其元素类型是CV_16U。Scalar_是一个模板向量,用来初始化矩阵的每个像素,因为矩阵具有4个通道,Scalar_有四个值。其运行结果:
运行结果首先打印了Mat中的矩阵,接着是Mat的各个属性。注意其type = 26,而depth = 2。这是由于上面所说的各种预定义类型
例如,CV_16UC4,CV_8U是一些预定义的常量。
step
Mat中的step是一个MStep的一个实例。其声明如下:
struct CV_EXPORTS MStep{MStep();MStep(size_t s);const size_t& operator[](int i) const;size_t& operator[](int i);operator size_t() const;MStep& operator = (size_t s);size_t* p;size_t buf[2];protected:MStep& operator = (const MStep&);};
从其声明中可以看出,MStep和size_t有比较深的关系。用size_t作为参数的构造函数和重载的赋值运算符
MStep(size_t s); MStep& operator = (size_t s);
向size_t的类型转换以及重载的[ ]运算符返回size_t
const size_t& operator[](int i) const;size_t& operator[](int i);
size_t的数组以及指针
size_t* p;size_t buf[2];
那么size_t又是什么呢,看代码
typedef unsigned int size_t;
size_t就是无符号整数。
再看一下MStep的构造函数,就可以知道其究竟保存的是什么了。
inline Mat::MStep::MStep(size_t s) { p = buf; p[0] = s; p[1] = 0; }
从MStep的定义可以知道,buff是一个size_t[2],而p是size_t *,也就是可以把MStep看做一个size_t[2]。那么step中保存的这个size_t[2]和Mat中的数据有何种关系呢。
step[0]是矩阵中一行元素的字节数。
step[1]是矩阵中一个元素的自己数,也就是和上面所说的elemSize相等。
上面说到,Mat中一个uchar* data指向矩阵数据的首地址,而现在又知道了每一行和每一个元素的数据大小,就可以快速的访问Mat中的任意元素了。下面公式:
step1
规整化的step,值为step / elemSize1。 定义如下:
inline size_t Mat::step1(int i) const { return step.p[i]/elemSize1(); }
仍以上例代码中定义的img为例,来看下step,step1具体的值:
img(3*4)的type是CV_16UC4,step[0]是其一行所占的数据字节数4 *4 * 16 / 8 = 32.
step[1] 是一个元素所占的字节数,img的一个元素具有4个通道,故:4 * 16 / 8 = 2
step1 = step / elemSize1,elemSize1是元素的每个通道所占的字节数。
N维的step(N > 2)
上面分析step是一个size_t[2],实际不是很正确,正确的来说step应该是size_t[dims],dims是Mat的维度,所以对于上面的二维的Mat来说,step是size_t[2]也是正确的。
下面就对三维的Mat数据布局以及step(维度大于3的就算了吧)。
上图引用自http://ggicci.blog.163.com/blog/static/210364096201261052543349/ 搜集资料时发现了这幅图,一切就变的简单了 感谢作者Ggicci
三维的数据在Mat中是按面来存储的,上图描述的很清晰,这里不再多说。
上面言道,step是一个size_t[dims],dims是维度。so,三维的step就是size_t[3]。其余的不多说了,看图就有了。下面来创建一个三维的Mat,实际看看
int dims[3] = { 3, 3, 3 };Mat src(3, dims, CV_16SC2, Scalar_<short>(1,2));cout << "step[0]:" << src.step[0] << endl;cout << "step[1]:" << src.step[1] << endl;cout << "step[2]:" << src.step[2] << endl;
首先创建一个3*3*3,depth为CV_16S的两通道的Mat
step[0]是一个数据面的大小 3 * 3 * (16 / 8 ) * 2 = 36
step[1]是一行数据的大小 3 * (16 / 8 ) * 2 = 12
step[2]是一个元素的大小 2 * (16 / 8) = 4
PS: 三维的Mat 不能使用 <<运算符进行输出的。
Part III
- 综述
Mat类可以被看做是OpenCV中C++版本的矩阵类,替代原来C版本的矩阵结构体CvMat和图像结构体IplImage;
Mat最大的优势跟STL的兼容性很好,有很多类似于STL的操作。但是Mat远远强于后者;
Mat是一种高效的数据类型,它对内存进行动态的管理,不需要之前用户手动的管理内存。
- Mat类定义
Mat类定义于core.hpp中,主要包含有两部分数据:一部分是矩阵头(matrix header),这部分的大小是固定的,包含矩阵的大小,存储的方式,矩阵存储的地址等等;另一个部分是一个指向矩阵包含像素值的指针(data)。Mat类的定义如下:
- <span style="font-size:12px;">class CV_EXPORTS Mat
- {
- public:
- // ... a lot of methods ...
- ...
- /*! includes several bit-fields:
- - the magic signature
- - continuity flag
- - depth
- - number of channels
- */
- int flags;
- //! the array dimensionality, >= 2
- int dims;
- //! the number of rows and columns or (-1, -1) when the array has more than 2 dimensions
- int rows, cols;
- //! pointer to the data
- uchar* data;
- //! pointer to the reference counter;
- // when array points to user-allocated data, the pointer is NULL
- int* refcount;
- // other members
- ...
- };</span>
- Mat数据类型
Mat的存储是逐行存储的,矩阵中的数据类型包括:Mat_<uchar>对应的是CV_8U,Mat_<uchar>对应的是CV_8U,Mat_<char>对应的是CV_8S,Mat_<int>对应的是CV_32S,Mat_<float>对应的是CV_32F,Mat_<double>对应的是CV_64F,对应的数据深度如下:
• 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矩阵
- <span style="font-size:12px;">//1.使用构造函数,常见的几个如下:
- Mat::Mat(); //default
- Mat::Mat(int rows, int cols, int type);
- Mat::Mat(Size size, int type);
- Mat::Mat(int rows, int cols, int type, const Scalar& s);
- Mat::Mat(Size size, int type, const Scalar& s);
- Mat::Mat(const Mat& m);
- //参数说明:
- //int rows:高
- //int cols:宽
- //int type:参见"Mat类型定义"
- //Size size:矩阵尺寸,注意宽和高的顺序:Size(cols, rows)
- //const Scalar& s:用于初始化矩阵元素的数值
- //const Mat& m:拷贝m的矩阵头给新的Mat对象,但是不复制数据!相当于创建了m的一个引用对象
- //例子1:创建100*90的矩阵,矩阵元素为3通道32位浮点型
- cv::Mat M(100, 90, CV_32FC3);
- //例子2:使用一维或多维数组来初始化矩阵,
- double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}};
- cv::Mat M = cv::Mat(3, 3, CV_64F, m);
- //2.使用create函数:
- Mat a = create(10, 9, CV_16U); //创建10*9的矩阵,矩阵元素为16位无符号整型
- //create的一个特殊用法:如果初始化的时候没有传入size的参数,或者后面需要改变size的参数,可以使用create来调整
- // make 7x7 complex matrix filled with 1+3j.
- cv::Mat M(7,7,CV_32FC2,Scalar(1,3));
- // and now turn M to 100x60 15-channel 8-bit matrix.
- // The old content will be deallocated:隐式使用release()释放
- M.create(100,60,CV_8UC(15));</span>
- 复制矩阵
参见另一篇博文:http://blog.csdn.net/holybin/article/details/17711013
- 合并矩阵
- //假设现有需要将n个CvMat类型的矩阵(每个都是1*m的行向量)合并到一个n*m(n行m列)的矩阵中,即:矩阵合并问题。
- CvMat* vector; //行向量:1*m
- Mat dst; //目标矩阵:n*m
- Mat vectorMat = Mat(vector, true); //将CvMat转为Mat
- Mat tmpMat = M.row(i); //注意:浅拷贝(参见"复制矩阵")
- vectorMat.copyTo(tmpMat); //注意:深拷贝(此时tmpMat已改变为vectorMat,即:目标矩阵的第i+1行被赋值为vectorMat)
- //以上为改变目标矩阵的i+1行的值,以此类推即可将n个行向量合并到目标矩阵中。
- 访问矩阵元素
- //1.at函数
- M.at<double>(i,j) += 1.f; //set (i,j)-th element
- int a = M.at<int>(i,j); //get (i,j)-th element
- //2.矩阵元素指针(ptr)
- for(int i = 0; i < M.rows; i++)
- {
- const double* pData = M.ptr<double>(i); //第i+1行的所有元素
- for(int j = 0; j < M.cols; j++)
- cout<<pData[j]<<endl;
- }
- Mat类成员函数详解
Mat::eye
返回一个恒等指定大小和类型矩阵。
C++: static MatExpr Mat::eye(int rows, int cols, inttype)
C++: static MatExpr Mat::eye(Size size, int type)
参数
rows –的行数。
cols– 的列数。
size –替代矩阵大小规格Size(cols, rows)的方法。
type – 创建的矩阵的类型。
该方法返回 Matlab 式恒等矩阵初始值设定项,类似 Mat::zeros()和 Mat::ones(),你可以用缩放操作高效地创建缩放的恒等矩阵:
/ / 创建4 x 4 的对角矩阵并在对角线上以0.1的比率缩小。
Mat A = Mat::eye(4, 4, CV_32F)*0.1;
Mat::create
C++: void Mat::create(int rows, int cols, int type)
C++: void Mat::create(Size size, int type)
C++: void Mat::create(int ndims, const int* sizes, inttype)
size – 替代新矩阵大小规格:Size(cols, rows)。
这是关键的Mat方法之一。大多数新样式 OpenCV 函数和产生阵列的方法每个输出数组都调用这个方法。此方法使用如下算法:
1.如果当前数组形状和类型匹配新的请立即返回。否则,通过调用 Mat::release()取消引用以前的数据。
3.分配新的 total()*elemSize() 个字节的数据空间。
这项计划使内存管理强大高效同时还为用户减少了额外输入。这意味着通常不需要显式分配输出数组。也就是说,可以不写成:
Mat gray(color.rows, color.cols,color.depth());
cvtColor(color, gray, CV_BGR2GRAY);
cvtColor(color, gray, CV_BGR2GRAY);
因为 cvtColor,与大多数 OpenCV 函数相同,在输出数组时内部调用Mat::create()。
Mat::addref
Mat::release
Mat::resize
C++: void Mat::resize(size_t sz)
C++: void Mat::resize(size_t sz, const Scalar& s)
该方法更改矩阵的行数。如果矩阵重新分配,第一最少(Mat::rows,sz) 行数要保留下来。该方法模拟相应的 STL 向量类的方法。
Mat::reserve
C++: void Mat::reserve(size_t sz)
该方法sz行存储空间。如果矩阵已经有足够的空间来存储sz行,没有任何异常发生。如果矩阵重新分配,保留前(Mat::rows) 行。该方法模拟了相应的STL 向量类的方法。
Mat::push_back
C++: template<typename T> voidMat::push_back(const T& elem)
C++: void Mat::push_back(const Mat& elem)
该方法将一个或多个元素添加到矩阵的底部。他们是模拟相应的 STL 向量类的方法。元素为Mat时,其类型和列的数目必须和矩阵容器是相同的。
Mat::pop_back
C++: template<typename T> voidMat::pop_back(size_t nelems=1)
nelems –删除的行的数目。如果它大于总的行数,则会引发异常。
Mat::locateROI
C++: void Mat::locateROI(Size& wholeSize,Point& ofs) const
wholeSize–输出参数,其中包含的整个矩阵包含大小 * 这是其中一部分。
Mat::adjustROI
C++: Mat& Mat::adjustROI(int dtop, int dbottom,int dleft, int dright)
Mat::operator()
C++: Mat Mat::operator()(Range rowRange, RangecolRange) const
C++: Mat Mat::operator()(const Rect& roi) const
C++: Mat Mat::operator()(const Ranges* ranges) const
rowRange –提取的子阵的开始和结束的行。不包括的上限。若要选择的所有行,请使用 Range::all()。
colRange –提取的子阵的开始和结束的列。不包括的上限。若要选择的所有列,请使用 Range::all()。
Mat::operator CvMat
C++: Mat::operator CvMat() const
该运算符创建矩阵 CvMat 的头,而不复制的基础数据。引用计数未被考虑到此操作中。因此,您应该确保CvMat 头在使用的时候不释放原始矩阵。该运算符对于新旧OpenCV API混用是有用的,例如:
Mat img(Size(320, 240), CV_8UC3);
其中 mycvOldFunc 是用于OpenCV 1.x 数据结构的函数。
Mat::operator IplImage
C++: Mat::operator IplImage() const
运算符创建矩阵 IplImage 头,而不复制的基础数据。您应该确保使用IplImage头时不释放原矩阵。与Mat::operatorCvMat类似,该运算符在OpenCV新旧API混用中很有用。
Mat::total
C++: size_t Mat::total() const
Mat::isContinuous
C++: bool Mat::isContinuous() const
/ / 等价的Mat::isContinuous() 的执行情况
boolmyCheckMatContinuity(const Mat& m)
//返回 (m.flags & Mat::CONTINUOUS_FLAG) != 0;
return m.rows ==1 || m.step == m.cols*m.elemSize();
void alphaBlendRGBA(const Mat& src1,const Mat& src2, Mat& dst)
const float alpha_scale =(float)std::numeric_limits<T>::max(),
CV_Assert( src1.type() == src2.type()&&
src1.type() ==CV_MAKETYPE(DataType<T>::depth, 4) &&
dst.create(size, src1.type());
if( src1.isContinuous() &&src2.isContinuous() && dst.isContinuous() )
for( int i = 0; i < size.height; i++ )
const T* ptr1 = src1.ptr<T>(i);
const T* ptr2 = src2.ptr<T>(i);
for( int j = 0; j < size.width; j += 4 )
float alpha = ptr1[j+3]*inv_scale, beta =ptr2[j+3]*inv_scale;
dptr[j] =saturate_cast<T>(ptr1[j]*alpha + ptr2[j]*beta);
dptr[j+1] =saturate_cast<T>(ptr1[j+1]*alpha + ptr2[j+1]*beta);
dptr[j+2] =saturate_cast<T>(ptr1[j+2]*alpha + ptr2[j+2]*beta);
dptr[j+3] = saturate_cast<T>((1 -(1-alpha)*(1-beta))*alpha_scale);
这种方法,不仅很简单,而且在简单的元素的操作中可以提高10-20%性能,尤其在图像很小且操作非常简单的时候。
Mat::elemSize
C++: size_t Mat::elemSize() const
该方法返回以字节为单位的矩阵元素大小。例如,如果矩阵类型是 CV_16SC3,该方法返回3*sizeof(short)或 6。
Mat::elemSize1
C++: size_t Mat::elemSize1() const
该方法返回以字节为单位的矩阵元素通道大小,也就是忽略通道的数量。例如,
如果矩阵类型是 CV_16SC3,该方法返回 sizeof(short) 或 2。
Mat::type
该方法返回一个矩阵的元素类型。这是兼容CvMat 类型系统,像 CV_16SC3标识符
Mat::depth
该方法返回矩阵元素深度(每个单独的通道类型)的标识符。例如,对于16位有符号的3通道数组,该方法返回CV_16S。矩阵类型的完整列表包含以下内容值:
• CV_16S-16 位符号整数 (-32768…..32767)
• CV_32S-32 位符号整数 (-2147483648……2147483647)
• CV_32F-32 位浮点数 (-FLT_MAX ………FLT_MAX,INF,NAN)
• CV_64F-64 位浮点数(-DBL_MAX ……….DBL_MAX,INF,NAN)
Mat::channels
C++: int Mat::channels() const
Mat::step1
C + +: size_t const Mat::step1()
该方法返回以矩阵的step除以Mat::elemSize1()。它对快速访问任意矩阵元素很有用。
Mat::size
该方法返回一个矩阵大小:Size(cols, rows)。矩阵超过 2 维时返回大小为(-1,-1)。
Mat::empty
Mat::ptr
C++: const uchar* Mat::ptr(int i=0) const
C++: template<typename _Tp> _Tp* Mat::ptr(inti=0)
C++: template<typename _Tp> const _Tp*Mat::ptr(int i=0) const
该方法返回uchar*,或指向由输入指定矩阵行的指针。参看Mat::isContinuous()的中示例了解如何使用这些方法。
Mat::at
C++: template<typename T> T& Mat::at(int i)const
C++: template<typename T> const T&Mat::at(int i) const
C++: template<typename T> T& Mat::at(int i,int j)
C++: template<typename T> const T&Mat::at(int i, int j) const
C++: template<typename T> T& Mat::at(Pointpt)
C++: template<typename T> const T&Mat::at(Point pt) const
C++: template<typename T> T& Mat::at(int i,int j, int k)
C++: template<typename T> const T&Mat::at(int i, int j, int k) const
C++: template<typename T> T& Mat::at(constint* idx)
C++: template<typename T> const T&Mat::at(const int* idx) const
Mat::begin
C++: template<typename _Tp>MatIterator_<_Tp> Mat::begin()
C++: template<typename _Tp>MatConstIterator_<_Tp> Mat::begin() const
该方法返回矩阵的只读或读写的迭代器。矩阵迭代器的使用和双向 STL 迭代器的使用是非常相似的。在下面的示例中,alpha融合函数是使用矩阵迭代器重写:
void alphaBlendRGBA(const Mat& src1,const Mat& src2, Mat& dst)
const float alpha_scale =(float)std::numeric_limits<T>::max(),
CV_Assert( src1.type() == src2.type()&&
src1.type() == DataType<VT>::type&&
dst.create(size, src1.type());
MatConstIterator_<VT> it1 =src1.begin<VT>(), it1_end = src1.end<VT>();
MatConstIterator_<VT> it2 =src2.begin<VT>();
MatIterator_<VT> dst_it =dst.begin<VT>();
for( ; it1 != it1_end; ++it1, ++it2,++dst_it )
float alpha = pix1[3]*inv_scale, beta =pix2[3]*inv_scale;
*dst_it =VT(saturate_cast<T>(pix1[0]*alpha + pix2[0]*beta),
saturate_cast<T>(pix1[1]*alpha + pix2[1]*beta),
saturate_cast<T>(pix1[2]*alpha +pix2[2]*beta),
saturate_cast<T>((1 -(1-alpha)*(1-beta))*alpha_scale));
Mat::end
返回矩阵迭代器,并将其设置为 最后元素之后(after-last)的矩阵元。
C++: template<typename _Tp>MatIterator_<_Tp> Mat::end()
C++: template<typename _Tp>MatConstIterator_<_Tp> Mat::end() const
参考文档:
1) http://blog.csdn.net/xiahouzuoxin/article/details/38298165
2) http://www.cnblogs.com/wangguchangqing/p/4016179.html
OpenCV Mat 简介相关推荐
- pybind opencv mat
如果c++中frame裁剪了,把裁剪的图传给python,图片会出现乱码,解决方法: crop后再进行 mat.clone(),返回pyhon就可以了. 这个也可以参考: https://blog.c ...
- c++ opencv mat 最大值,数据类型
这个好像对的: cv::Mat image0 = cv::imread("../configs/bus.jpg", cv::IMREAD_UNCHANGED);cv::Mat ds ...
- opencv mat相关资料整理
https://github.com/izhaolei/cl-cv convert OpenCV Mat class to opencl IMage QImage2Mat https://github ...
- OpenCV Mat类详解和用法(官网原文)
参考文章:OpenCV Mat类详解和用法 我马克一下,日后更 官网原文链接:https://docs.opencv.org/3.2.0/d6/d6d/tutorial_mat_the_basic_i ...
- OpenCV Tracker简介
OpenCV Tracker简介 OpenCV Tracker简介 目标 源代码 解释 设置输入视频 声明所需的变量 创建一个跟踪器对象 选择被跟踪的对象 初始化跟踪器对象 更新 OpenCV Tra ...
- Julia OpenCV绑定简介
Julia OpenCV绑定简介 Julia OpenCV绑定简介 OpenCV 茱莉亚(Julia) 绑定 如何建立绑定 Sample Usage 运行包含的样本 Julia OpenCV绑定简介 ...
- Clojure开发OpenCV的简介
Clojure开发OpenCV的简介 Clojure开发OpenCV的简介 我们将在本教程中做什么 前言 安装Leiningen 安装localrepo Leiningen插件 将特定于Java的li ...
- FFmpeg转OpenCV Mat显示
FFmpeg一般采用SDL进行显示,如果不追求复杂的界面.交互和多线程功能,当然也可以使用OpenCV的imshow()方法进行显示了,而且实现起来比SDL更简单.方法也很简单,只需要把视频帧的BGR ...
- Dlib学习笔记:解决dlib array2d转 OpenCV Mat时颜色失真
Dlib学习笔记:解决dlib array2d转 OpenCV Mat时颜色失真 [尊重原创,转载请注明出处] http://blog.csdn.net/guyuealian/article/deta ...
最新文章
- ios--用证书进行真机调试(转)
- 计算机图像抠图有什么作用,图像处理 抠图|傲软抠图 v1.1.13.1电脑版 - 系统天堂...
- python和对象复习_【Python复习巩固 Day4】面向对象编程
- python find函数_Python 速学!不懂怎么入门python的小白看这篇就够了!
- c++ set 遍历_47. Set 是如何工作的(3) 遍历顺序是如何确定的?
- 第十一期:30秒内便能学会的30个实用Python代码片段
- Windows 文件含义大全
- 11.11开启10分钟 达达承接的京东小时购首单已签收
- 小米12系列或首发2亿像素主摄:配原生1英寸超大底
- Emmet 简写语法
- 山石网科-Hillstone-L2TP-***之配置终结篇
- c语言有理数均值思路,5-35 有理数均值 (20分)
- PVNet(6D姿态估计)
- 视频通信系统的关键技术与挑战
- cad批量打印_CAD如何进行批量打印图纸
- 网易云评论 爬虫 java_网易云歌曲评论爬虫如何实现翻页?
- 微信小程序 java四六级英语学习助手系统app
- Google搜索中国定制版已黄了,百度再次PK的希望或落空
- 如何获取LINUX主机所有的IP
- 高分2(GF2)卫星数据系列处理
热门文章
- 涂抹mysql 完整_涂抹mysql笔记-管理mysql服务
- 嵌入式Linux下跑自整定pid,告诉过你PID很重要,你不听
- Unity3D研究院之C#使用Socket与HTTP连接服务器传输数据包
- 用计算机计算线性卷积的基本规则,实验三_线性卷积与圆周卷积的计算.doc
- 胡扯JS系列-匿名函数的自动运行
- 剖析nodejs的事件循环
- 在刷一道题,数字回文,以以前做过,刚好昨天也做了一个类似的题,数字反转,原理有点像-----9. Palindrome Number...
- 一脸懵逼学习Storm的搭建--(一个开源的分布式实时计算系统)
- 【Alpha】开发日志Day4-0715
- 项目经理的几个重要转变