OpenCV学习(3)--Mat矩阵的操作

CvMat的矩阵结构

 1 typedef struct CvMat
 2 {
 3     //矩阵中元素的类型
 4     int type;
 5     //行数据长度
 6     int step;
 7
 8     /* for internal use only */
 9     int* refcount;
10     int hdr_refcount;
11
12     //指向数据的指针
13     union
14     {
15         uchar* ptr;
16         short* s;
17         int* i;
18         float* fl;
19         double* db;
20     } data;
21
22 #ifdef __cplusplus
23     //矩阵的行数
24     union
25     {
26         int rows;
27         int height;
28     };
29     //矩阵的列数
30     union
31     {
32         int cols;
33         int width;
34     };
35 #else
36     int rows;
37     int cols;
38 #endif
39
40 }
41 CvMat;

矩阵的type的预定义类型为:CV_<bit_depth>(S|U|F)C(number_of_channels)。所以矩阵的元素可以是32位浮点型数据(CV_32FC1),或者是无符号的8位三元组的整型数据(CV_8UC3),一个CvMat的元素不一定就是个单一的数字,一般更可能是一个向量。

行数据长度step用字节表示而不是整型或者浮点型长度。

但是这个type在对Mat初始化以后,会通过一个宏把它装换成一个数值:

1 #define CV_32FC1 CV_MAKETYPE(CV_32F,1)
2 #define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))

下面说一下创建矩阵的方法:

创建一个矩阵方法一:

1 /* Allocates and initializes CvMat header and allocates data */
2 CVAPI(CvMat*)  cvCreateMat( int rows, int cols, int type );

指向数据部分的指针有各种类型的,但是他们的起始地址是一样的。

创建矩阵的方法二:

创建CvMat结构体,但是不分配内存

1 /* Allocates and initalizes CvMat header */
2 CVAPI(CvMat*)  cvCreateMatHeader( int rows, int cols, int type );

分配数据所需要的内存

1 /* Allocates array data */
2 CVAPI(void)  cvCreateData( CvArr* arr );

创建矩阵方法三:

克隆矩阵

1 /* Creates an exact copy of the input matrix (except, may be, step value) */
2 CVAPI(CvMat*) cvCloneMat( const CvMat* mat );

该函数根据现有的矩阵克隆一个新的矩阵,分配独立的内存空间,需要使用单独的cvReleaseMat函数释放内存空间。

创建矩阵方法四:

在已有的CvMat结构体上初始化矩阵,这样的结果是数组和矩阵的数据部分有相同的内存空间。

1 /* Initializes CvMat header */
2 CVAPI(CvMat*) cvInitMatHeader( CvMat* mat, int rows, int cols,
3                               int type, void* data CV_DEFAULT(NULL),
4                               int step CV_DEFAULT(CV_AUTOSTEP) );

注意这个函数的第一个参数,一定要是初始化的结构体,不能只是一个空指针,所以可以这样用:

1 CvMat pMat;
2 float data[4] = {3,4,5,7};
3
4 cvInitMatHeader(&pMat, 2, 2, CV_32FC1, data);

但是不可以这样:

1 CvMat* pMat;
2 float data[4] = {3,4,5,7};
3
4 cvInitMatHeader(pMat, 2, 2, CV_32FC1, data);

因为pMat是一个没有初始化的指针。

有关CvMat数据内存空间的释放:

上面的着三种方式的数据内存都是开辟在堆内存中的,所以要释放占用的内存。

1 /* Releases CvMat header and deallocates matrix data
2    (reference counting is used for data) */
3 CVAPI(void)  cvReleaseMat( CvMat** mat );

OpenCV学习(3)--Mat矩阵的操作

时间: 2025-01-16 19:15:02

OpenCV学习(3)--Mat矩阵的操作的相关文章

opencv学习笔记(01)——操作图像的像素

1 #include <opencv2\core\core.hpp> 2 #include <opencv2\highgui\highgui.hpp> 3 #include <opencv2\imgproc\imgproc.hpp> 4 #include <iostream> 5 6 7 void salt(cv::Mat& image, int n) 8 { 9 10 for(int k=0; k<n; k++) 11 { 12 13 int

OpenCV学习:Mat结构中的数据共享机制

使用Mat类,内存管理变得简单,不再像使用IplImage那样需要自己申请和释放内存. Mat是一个类,由两个数据部分组成:矩阵头(包含矩阵尺寸,存储方法,存储地址等信息)和一个指向存储所有像素值的矩阵的指针. 矩阵头的尺寸是常数值,但矩阵本身的尺寸会依图像的不同而不同,通常比矩阵头的尺寸大数个数量级. 复制矩阵数据往往花费较多时间,因此除非有必要,不要复制大的矩阵. 为了解决矩阵数据的传递,OpenCV使用了引用计数机制.其思路是让每个Mat对象有自己的矩阵头信息,但多个Mat对象可以共享同一

opencv学习 2.Mat类图像遍历

图像的遍历 原图 1.简单存取像素值 代码如下: // Mat类图像遍历.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include "cv.h" #include "cxcore.h" #include "highgui.h" using namespace std; using namespace cv; int _tmain(int argc, _TCHAR* argv[])

opencv学习笔记(05)——操作相邻区域

下面的例子以灰度图像为例: #include <opencv2\highgui\highgui.hpp> #include <opencv2\imgproc\imgproc.hpp> #include <opencv2\core\core.hpp> using namespace cv; void sharpen(const cv::Mat& img_original, cv::Mat& img_altered); void sharpen2D(cons

OpenCV 学习(像素操作 Manipuating the Pixels)

OpenCV 学习(像素操作 Manipuating the Pixels) OpenCV 虽然提供了许多类型的图像处理函数,可以对图像进行各种常见的处理,但是总会有些操作时没有的,这时我们就需要自己来操纵像素,实现我们需要的功能.今天就来讲讲 OpenCV 进行像素级操作的几种方法,并做个比较. 在 OpenCV 中,图像用矩阵来表示,对应的数据类型为 cv::Mat . cv::Mat 功能很强大,矩阵的元素可以为字节.字.浮点数.数组等多种形式.对于灰度图像,每个像素用一个 8 bit 字

opencv中Mat类型数据操作与遍历

Mat作为opencv中一种数据类型常常用来存储图像,相对与以前的IplImgae类型来说,Mat类型省去了人工的对内存的分配与释放,转而自动分配释放.Mat Class主要包括两部个数据部分:一个是matrix header(包括matrix的大小尺寸,储存方法,储存地址等等..),另一个是指向存储像素值的矩阵的指针. Opencv中对Mat的复制分为两种, Mat A, C; // creates just the header parts A = imread(argv[1], CV_LO

OpenCv学习笔记(一)----OpenCv中Mat类源码的详细解读(2)

(一)像素存储的方法 1--本节我们讲解如何存储像素,存储像素值,需要指定: 1--颜色空间 2--数据类型 2--其中,颜色空间是指针对一个给定的颜色,如何组合颜色以其编码. 3--最简单的颜色空间是----灰度级空间----只需要处理:黑色和白色,对它们进行组合便可以产生不同程度的灰 色(256灰度级) 4--对于彩色方式---则有更多种类的颜色空间,但不论那种方式,都是把颜色分成:三个或者四个---基元素,通过 组合基元素,就可以产生所有的颜色 1--RGB颜色空间是最常用的一种颜色空间,

openCV学习笔记(9)Mat与IplImage,CvMat类型之间转换

opencv中图像数据容器一般有Mat,cvMat和IplImage.我们在平常的代码中,由于不同的函数的参数类型不一致,经常需要转换这三者之间的相互转化.网上有大量的杂七杂八的资料,望结合实际而用之. Mat是一个多维的密集数据数组,可以用来处理向量和矩阵.图像.直方图等等常见的多维数据,所以Mat侧重于计算,数学性较高,openCV对Mat类型的计算也进行了优化. 而CvMat和IplImage类型更侧重于"图像",opencv对其中的图像操作(缩放.单通道提取.图像阈值操作等)进

OpenCV 显示Mat矩阵异常 显示“程序停止工作” 解决办法

笔者调试OpenCV 程序时,在使用标准输出显示Mat矩阵时,编译没有错误,但每次运行都弹出程序停止工作的对话框.google之,得到解决方案. 程序如下: 1 #include <iostream> 2 #include <opencv2\opencv.hpp> 3 using namespace std; 4 using namespace cv; 5 6 int main() 7 { 8 Mat M = (Mat_<uchar>(2,2) << 1,2