OpenCV中的数据结构
来源:互联网 发布:mac三维建模软件 编辑:程序博客网 时间:2024/05/11 19:33
图像的存储方式
在之前的程序中,我们已经使用过IplImage这个数据类型,IplImage是OpenCV1.0中图像的基本数据结构,也是OpenCV1.0最常用的数据类型。下图为我们展示了三种数据结构之间的继承或派生关系:
虽然,OpenCV1.0是用C语言实现的,但我们仍然可以在此运用面向对象的思想。
CvArr , CvMat , IplImage 均为结构体,IplImage由CvMat派生,而CvMat由CvArr派生。先查看CvArr 的定义:
可以看到CvArr 并没有具体数据类型的定义,由注释可知,CvArr仅作为函数中接收结构体数据的形参来使用,可视为CvMat和CvArr 的抽象父类。实际上,在OpenCV1.0的库函数中,有大量的函数原型的形参都是CvArr* 类型的,可 用来接收CvMat*和IplImage*数据类型 。
继续看CvMat 的定义:
typedef structCvMat
{
int type;
int step;
/* for internal use only */
int* refcount;
int hdr_refcount;
union
{
uchar* ptr;
short* s;
int* i;
float* fl;
double* db;
} data;
#ifdef __cplusplus
union
{
int rows;
int height;
};
union
{
int cols;
int width;
};
#else
int rows;
int cols;
#endif
}
CvMat;
由源代码可知,CvMat数据类型包括行(高度),列(宽度),类型(type),行数据长度(step),和指向数据的指针(data),所以CvMat实际上是一个矩阵头,存储了矩阵数据的描述信息。包括IplImage和Mat在内的图像容器,都是这种将矩阵头和数据体分开的形式,通过矩阵头的数据指针指向数据体的内存位置。
创建CvMat数据
CvMat* cvCreateMat(introws, int cols, int type); /*创建矩阵头并分配内存*/
CV_INLine CvMat cvMat((introws, int cols, int type, void*data CV_DEFAULT); /*用已有数据data初始化矩阵*/
CvMat * cvInitMatHeader(CvMat * mat, int rows, intcols, int type, void * data CV_DEFAULT(NULL), int step CV_DEFAULT(CV_AUTOSTEP));/*(用已有数据data创建矩阵头)*/
对于矩阵数据的访问,OpenCV提供了一些宏和库函数来实现,如:
CV_MAT_ELEM();
cvPtr1D(),cvPtr2D(),cvPtr3D(),cvPtrND()
但存取数据最有效和便捷的办法应该是通过CVMat数据结构里的data成员直接访问,示例代码如下:
introws = mat->rows;
intcols = mat->cols;
cout<<rows<<endl;
cout<<cols<<endl;
for(int i = 0;i<rows;i++)
{
for(int j=0;j<cols;j++)
{
cout<<(int)*(mat->data.ptr + j +i*mat->step)<<'\t';
}
cout<<endl;
}
IplImage的定义:
typedef struct_IplImage
{
int nSize; /* sizeof(IplImage) */
int ID; /* version (=0)*/
int nChannels; /* Most of OpenCV functionssupport 1,2,3 or 4 channels */
int alphaChannel; /* Ignored by OpenCV */
int depth; /* Pixel depth in bits:IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S,
IPL_DEPTH_32S,IPL_DEPTH_32F and IPL_DEPTH_64F are supported. */
char colorModel[4]; /* Ignored by OpenCV*/
char channelSeq[4]; /* ditto */
int dataOrder; /* 0 - interleaved colorchannels, 1 - separate color channels.
cvCreateImagecan only create interleaved images */
int origin; /* 0 - top-left origin,
1 - bottom-leftorigin (Windows bitmaps style). */
int align; /* Alignment of image rows (4or 8).
OpenCV ignoresit and uses widthStep instead. */
int width; /* Image width inpixels. */
int height; /* Image height inpixels. */
struct _IplROI *roi; /* Image ROI. IfNULL, the whole image is selected. */
struct _IplImage *maskROI; /* Must be NULL. */
void *imageId; /* " " */
struct _IplTileInfo *tileInfo; /* " " */
int imageSize; /* Image data size in bytes
(==image->height*image->widthStep
in case ofinterleaved data)*/
char *imageData; /* Pointer to alignedimage data. */
int widthStep; /* Size of aligned image rowin bytes. */
int BorderMode[4]; /* Ignored byOpenCV. */
int BorderConst[4]; /* Ditto. */
char *imageDataOrigin; /* Pointer to veryorigin of image data
(not necessarilyaligned) -
needed forcorrect deallocation */
}
IplImage;
相比于CVMat,IplImage增加了一些成员变量使之可被解释为图像。一些重要的成员变量如下:
int width:图像宽度(列)
int height:图像高度(行)
int widthStep:矩阵中每一行数据所占的内存大小
int imageSize:图像在所占内存空间大小,单位为字节(注意:与成员变量nSize区别开,nSize 返回的是sizeof(IplImage),即矩阵头的大小,
imageSize==image->height*image->widthStep,即数据矩阵所占空间大小)
int nChannels: 通道数
相应输出:
char*imageData :指向图像数据的指针,CVMat中的data
代码(按行遍历输出数据):
输出结果:
关于通道的概念:
比较通俗易懂的解释是:灰度图的通道数为1,彩色图的通道为3。基本上,描述一个像素点,如果是灰度,那么只需要一个数值来描述它,就是单通道。如果一个像素点,有RGB三种颜色来描述它,就是三通道。
实际上,通道数可取的值是1,2,3和4.
灰度图(单通道):
RGB图(三通道):
现在考虑之前的代码,采用彩色图的读取方式,通道值为3,从之前的输出可以看到成员width和widthStep正好是1:3的关系;
将图像的读取方式改为灰度图,再进行输出如下:
此时width和widthStep正好相等,imageSize也缩小为原来的1/3,读者可自行检测。
Mat数据类型:
Mat是opencv2.0推出的新的数据结构,基本可以取代之前的cvMat和lplImage,相比之下Mat最大的好处就是能够更加方便的进行内存管理,不再需要程序员手动管理内存的释放。
源文件中的定义:
。。。
太长了。。。
OpenCV2.0之后采用C++实现,真正引入了面向对象的思想,Mat是一个类,同样有矩阵头和数据体两部分,部分定义如下:
class CV_EXPORTS Mat{ public: /*..很多方法..*//*............*/ int flags;(Note :目前还不知道flags做什么用的)int dims; /*数据的维数*/int rows,cols; /*行和列的数量;数组超过2维时为(-1,-1)*/uchar *data; /*指向数据*/int * refcount; /*指针的引用计数器; 阵列指向用户分配的数据时,指针为 NULL /* 其他成员 */ ... };
重要成员变量:
rows,cols: 行和列,等同于lplImage中的width和height
data:指向存储像素值的矩阵的指针,等同于lplImage中的imageData
refcount:OpenCV是用了引用计数机制,每个Mat对象都有自己的信息头,但可以共享同一个矩阵,通过data指针指向同一地址来实现。当进行复制的时候,只复制信息头,而不进行矩阵的复制。
在理解CVMat和lplImage之后,再来看Mat数据类型就不难了,可以自行阅读Mat类定义的源代码,以获得更深层次 的理解。
OpenCV中其他基本数据类型
结构
成员
意义
Point或point2i(f)
x,y
二维点
Point3i(f)
x,y,z
三维点
Size
width,height
图像尺寸
Rect
x,y,width,height
矩形
Scalar
double val[4]
颜色的表示
OPenCV1.0中的版本:
结构
成员
意义
CvPoint
int x,y
图像中的点
CvPoint2D32f
float x,y
二维点
CvPoint3D32f
float x,y,z
三维点
CvSize
int width,height
图像尺寸
CvRect
int x,y,width,height
矩形
CvScalar
double val[4]
颜色的表示
- OpenCV中的数据结构
- 讨论OpenCV中的数据结构
- OpenCV中的数据结构
- OPENCV中的数据结构总结
- OPENCV中的数据结构总结
- [OpenCV基础] 详细讨论OpenCV中的数据结构
- 详细讨论OpenCV中的数据结构
- 详细讨论OpenCV中的数据结构
- OpenCV中的数据结构CvSeq(序列)
- OpenCV中的数据结构CvSeq(序列)
- Android OpenCV中的几种基本数据结构
- opencv 数据结构
- OpenCV----OpenCV基础数据结构
- OpenCV里IplImage数据结构中的width和widthStep
- 我的OpenCV学习笔记(24):详细讨论OpenCV中的数据结构
- Opencv学习笔记(二):Opencv中的基本数据类型与数据结构
- opencv 数据结构之一opencv cvScalar
- openCV 常用数据结构
- C++之可变参数的实现简介
- Ubuntu下使用GStreamer开发简单的mp3播放器
- DEM提取一定高程值范围像元
- 12、osg中的雪花效果
- 添加窗体控件
- OpenCV中的数据结构
- 数据结构与算法——在一定范围内求最少标记点
- AutoCompleteTextView
- Excel Sheet Column Number
- 使用简单jQuery工具来实现表单的验证
- android小技巧
- Linux环境PHP7.0安装
- 05 简易计算器
- LeetCode 27:Remove Element