opencv中的Mat由两个数据部分组成:
1 矩阵头(包含矩阵的尺寸,存储方法,存储地址等信息),矩阵头的尺寸是常数值
2 指向存储所有像素值的矩阵(根据所选存储方法的不同矩阵可以是不同的维数)的指针
以下操作会说明了矩阵的内存操作:
Mat A,C;//只创建信息头部分
A = imread();//这里为矩阵开辟内存
Mat B(A);//使用拷贝构造函数,B和A的信息头不同,但是是指向同一块内存
C = A;//赋值运算符,C和A也是指向同一块内存
//注意,以下操作没有发生内存拷贝
Mat D(A,Rect(10,10,100,100));//返回Rect区域内的信息头
Mat E = A(Range:all(),Range(1,3));//返回指定的区域的信息头
如果需要对内存区域进行拷贝的话需要使用以下的两个函数:
clone()或者copyT0();
Mat的一些常见的函数解释:
Mat img = imread();//
Mat a=img.row(i);//为img的第i行创建一个矩阵头,对a的操作实际上也是对img的第i行的操作
Mat b=img.col(j);//同上面是一样的
Mat c=img.colRange(1,8);//为矩阵的第1到第8列创建一个矩阵头
Mat d=img.rowRange(1,8);//同上面是一样的
float* ptr=img.ptr<float>(0);//是返回的img的第0行的指针
Mat中的Mat_是对Mat的包装:
Mat_是继承自Mat的模版类,
在用Mat_初始一个Mat的时候需要指定相应的数据类型:
Mat_在对元素数据有大量的访问的时候就会显得效率比较高:
Mat M(100,100,CV_8U);
如果通过Mat::at<_Tp>(int y,int x);访问和通过
Mat_::operator()(int y,int x);访问效果是完全一致的,但是显然后者访问更简单
如:
Mat_<double> M(20,20);
for(int i=0;i<M.rows;i++)
{
for(int j=0;j<M.cols;j++)
{
M(i,j) = 1./(i+j+1);
}
}
但是如下访问会出错:
Mat M(100,100,CV_8U);
Mat_<float>& M1 = (Mat_<float>&)M;
M1(99,99) = 1.f;
对于一个多通道图像,使用如下:
Mat_<Vec3b> img(240,320,Vec3b(0,255,0));
for( int i = 0; i < 100; i++)
img(i,i) =Vec3b( 255, 255, 255);
// and now scramble the 2nd (red) channel of each pixel
for( int i = 0; i < img.rows; i++)
for( int j = 0; j < img.cols; j ++)
1 矩阵头(包含矩阵的尺寸,存储方法,存储地址等信息),矩阵头的尺寸是常数值
2 指向存储所有像素值的矩阵(根据所选存储方法的不同矩阵可以是不同的维数)的指针
以下操作会说明了矩阵的内存操作:
Mat A,C;//只创建信息头部分
A = imread();//这里为矩阵开辟内存
Mat B(A);//使用拷贝构造函数,B和A的信息头不同,但是是指向同一块内存
C = A;//赋值运算符,C和A也是指向同一块内存
//注意,以下操作没有发生内存拷贝
Mat D(A,Rect(10,10,100,100));//返回Rect区域内的信息头
Mat E = A(Range:all(),Range(1,3));//返回指定的区域的信息头
如果需要对内存区域进行拷贝的话需要使用以下的两个函数:
clone()或者copyT0();
Mat的一些常见的函数解释:
Mat img = imread();//
Mat a=img.row(i);//为img的第i行创建一个矩阵头,对a的操作实际上也是对img的第i行的操作
Mat b=img.col(j);//同上面是一样的
Mat c=img.colRange(1,8);//为矩阵的第1到第8列创建一个矩阵头
Mat d=img.rowRange(1,8);//同上面是一样的
float* ptr=img.ptr<float>(0);//是返回的img的第0行的指针
Mat中的Mat_是对Mat的包装:
Mat_是继承自Mat的模版类,
在用Mat_初始一个Mat的时候需要指定相应的数据类型:
Mat_在对元素数据有大量的访问的时候就会显得效率比较高:
Mat M(100,100,CV_8U);
如果通过Mat::at<_Tp>(int y,int x);访问和通过
Mat_::operator()(int y,int x);访问效果是完全一致的,但是显然后者访问更简单
如:
Mat_<double> M(20,20);
for(int i=0;i<M.rows;i++)
{
for(int j=0;j<M.cols;j++)
{
M(i,j) = 1./(i+j+1);
}
}
但是如下访问会出错:
Mat M(100,100,CV_8U);
Mat_<float>& M1 = (Mat_<float>&)M;
M1(99,99) = 1.f;
对于一个多通道图像,使用如下:
Mat_<Vec3b> img(240,320,Vec3b(0,255,0));
for( int i = 0; i < 100; i++)
img(i,i) =Vec3b( 255, 255, 255);
// and now scramble the 2nd (red) channel of each pixel
for( int i = 0; i < img.rows; i++)
for( int j = 0; j < img.cols; j ++)
img(i,j)[ 2] ^= (uchar)(i ^ j);
lliyuanzh@163.com