OpenCV中的Mat
来源:互联网 发布:华泰软件工程有限公司 编辑:程序博客网 时间:2024/06/05 04:38
(一)Mat矩阵中数据指针Mat.data是uchar类型指针,CV_8U系列可以通过计算指针位置快速地定位矩阵中的任意元素。
二维单通道元素可以用Mat::at(i, j)访问,i是行序号,j是列序号。
但对于多通道的非unsigned char类型矩阵来说,以上方法都不好(注:后来知道可以通过类型转换,用指针访问data数据,见后文)。可以用Mat::ptr()来获得指向某行元素的指针,在通过行数与通道数计算相应点的指针。
参照OpenCV的Mat::at()函数,写了一个访问二维Mat矩阵的两个简单的小函数,没有边界检查。
1
#include <opencv2/core/core.hpp>
2
3
template
<
typename
ItemType>
4
ItemType* getMatPointPtr(cv::Mat & src,
int
i ,
int
j ,
int
c = 0)
5
{
6
ItemType* curRow = src.ptr<ItemType>(i);
7
return
curRow + j * src.channels() + c;
8
}
9
template
<
typename
ItemType>
10
ItemType getMatPoint(cv::Mat & src,
int
i ,
int
j ,
int
c = 0)
11
{
12
ItemType* curRow = src.ptr<ItemType>(i);
13
return
*(curRow + j * src.channels() + c);
14
}
OpenCV中的Mat::at()代码有严格的边界检测,Mat::ptr()也有边界检测,但代码中没有检测j是否越界。
以上为推荐使用的情况,下边的不推荐使用。
可以通过转换指针类型,访问非uchar类型的Mat元素。
例如图像是CV_64FC1格式,可以将Mat.data指针直接转换成double*类型:
1
// imgMat is a image.
2
double
* pimg = (
double
*)(imgMat.data)
也可以用C++中的显式转换符static_cast,不过要通过void*类型过渡:
1
void
* pvoid =
static_cast
<
void
*>(imgMat.data);
2
double
* pimg =
static_cast
<
double
*>(pvoid);
这种方式在Debug模式下速度提升非常显著,但没有任何的边界检查和异常处理,使用时必须十分小心。使用Mat::ptr的速度和直接使用这种方法差不多,多一层保护总比没有保护强。
(二)
- Mat A, C; //只创建信息头部分
- A = imread(argv[1], CV_LOAD_IMAGE_COLOR); //这里为矩阵开辟内存
- MatB(A); //使用拷贝构造函数
- C = A; //赋值运算符
- Mat D(A, Rect(10, 10, 100, 100)); //using a rectangle
- Mat E = A(Range:all(), Range(1, 3)); //using row and column boundaries
- Mat F = A.clone();
- Mat G;
- A.copyTo(G);
9.现在改变 F 或者 G 就不会影响 Mat 信息头所指向的矩阵。总结一下,你需要记住的是
- OpenCV函数中输出图像的内存分配是自动完成的(如果不特别指定的话)。
- 使用OpenCV的C++接口时不需要考虑内存释放问题。
- 赋值运算符和拷贝构造函数( ctor )只拷贝信息头。
- 使用函数 clone() 或者 copyTo() 来拷贝一副图像的矩阵。
补充(空间存储):
10.对于 彩色 方式则有更多种类的颜色空间,但不论哪种方式都是把颜色分成三个或者四个基元素,通过组合基元素可以产生所有的颜色。- HSV和HLS把颜色分解成色调、饱和度和亮度/明度。这是描述颜色更自然的方式,比如可以通过抛弃最后一个元素,使算法对输入图像的光照条件不敏感。
- YCrCb在JPEG图像格式中广泛使用。
- CIE L*a*b*是一种在感知上均匀的颜色空间,它适合用来度量两个颜色之间的 距离 。
显式地创建一个 Mat 对象
- Mat M(2,2, CV_8UC3, Scalar(0,0,255));
- cout << "M = " << endl << " " << M << endl << endl;
然后,需要指定存储元素的数据类型以及每个矩阵点的通道数。为此,依据下面的规则有多种定义
- CV_[The number of bits per item][Signed or Unsigned][Type Prefix]C[The channel number]
14.比如 CV_8UC3 表示使用8位的 unsigned char 型,每个像素由三个元素组成三通道。预先定义的通道数可以多达四个。 Scalar 是个short型vector。指定这个能够使用指定的定制化值来初始化矩阵。当然,如果你需要更多通道数,你可以使用大写的宏并把通道数放在小括号中,如下所示
15.在 C\C++ 中通过构造函数进行初始化
- int sz[3] = {2,2,2};
- Mat L(3,sz, CV_8UC(1), Scalar::all(0));
16.上面的例子演示了如何创建一个超过两维的矩阵:指定维数,然后传递一个指向一个数组的指针,这个数组包含每个维度的尺寸;其余的相同
为已存在IplImage指针创建信息头:
- IplImage* img = cvLoadImage("greatwave.png", 1);
- Mat mtx(img); // convert IplImage* -> Mat
Create() function: 函数
- M.create(4,4, CV_8UC(2));
- cout << "M = "<< endl << " " << M << endl << endl;
17.这个创建方法不能为矩阵设初值,它只是在改变尺寸时重新为矩阵数据开辟内存。
MATLAB形式的初始化方式: zeros(), ones(), :eyes() 。使用以下方式指定尺寸和数据类型:
[cpp] view plaincopy
- Mat E = Mat::eye(4, 4, CV_64F);
- cout << "E = " << endl << " " << E << endl << endl;
- Mat O = Mat::ones(2, 2, CV_32F);
- cout << "O = " << endl << " " << O << endl << endl;
- Mat Z = Mat::zeros(3,3, CV_8UC1);
- cout << "Z = " << endl << " " << Z << endl << end
*对于小矩阵你可以用逗号分隔的初始化函数:
- Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
- cout << "C = " << endl << " " << C << endl << endl;
*使用 clone() 或者 copyTo() 为一个存在的 Mat 对象创建一个新的信息头。
- Mat RowClone = C.row(1).clone();
- cout << "RowClone = " << endl << " " << RowClone << endl << endl;
- opencv中的Mat
- OpenCV中的Mat
- OPENCV中的mat学习
- opencv中的Mat类型
- opencv中的Mat
- OpenCV中的Mat函数
- OpenCV中的Mat, cvMat, IplImage
- (转)OpenCV中的Mat
- OpenCV中的Mat阵列操作
- opencv中的Mat结构操作
- openCV中的MAT的详解
- opencv中的Mat矩阵运算
- opencv中的Mat使用相关说明
- openCV中的Mat、IplImage数据的转换
- opencv中的Mat类型的相关概念
- OpenCV里面Mat方法中的Scalar详解
- OpenCV里面Mat方法中的Scalar详解
- QImage与OpenCV中的MAT图像格式转换
- IE Javascript 进阶调试
- UVALive - 2519 Radar Installation
- 五分钟精通Oracle表空间
- Android应用程序包扫描过程源码分析
- 哑铃健身计划及图解说明
- OpenCV中的Mat
- 安装 gdb insight
- UITextField的详细用法,包括具体协议(限制内容和大小等)
- 可到达性(算法导论22-4)
- 五种Oracle用户的授权与管理
- 全面讲解Oracle查询用户表空间
- Android 移动动画- TranslateAnimation(转)
- 学习 JS 继承
- java正则表达式