您的位置:首页 > 运维架构

【Ubuntu+OpenCV】OpenCV之矩阵创建、初始化--学习笔记【4】

2011-06-15 16:58 711 查看
一、矩阵的创建

矩阵有多种创建
方法,也就是说定义个一个矩阵变量有多种办法:

(1)最常见的方法是用cvCreateMat()

,它由两个原函数组成,cvCreateMatHeader
()

cvCreateData
()


//Create a new rows by cols matrix of type 'type'.
//
CvMat* cvCreateMat( int rows, int cols, int type );


type: 矩阵元素类型. 格式为CV_<bit_depth>(S|U|F)C<number_of_channels>.

例如: CV_8UC1 表示8位无符号单通道矩阵, CV_32SC2表示32位有符号双通道矩阵.
例程:
CvMat* M = cvCreateMat(4,4,CV_32FC1);


创建一个4X4的矩阵,矩阵的元素的数据类型时float(不是double型!!)

cvCreateMat

Creates a matrix header and allocates the matrix data.

创建一个矩阵头并且为矩阵数据分配内存空间

CvMat* cvCreateMat(

int rows,

int cols,

int type);

rows Number of rows in the matrix//矩阵的行数

cols Number of columns in the matrix//矩阵的列数

type

The type of the matrix elements in the form CV <bit depth><S|U|F>C<number of

channels>, where S=signed, U=unsigned, F=float. For example, CV 8UC1 means the

elements are 8-bit unsigned and the there is 1 channel, and CV 32SC2 means the elements

are 32-bit signed and there are 2 channels.

cvCreateMat实际上就是以下形式的一种简洁形式

This is the concise form for:

CvMat* M = cvCreateMatHeader(4, 4, CV_32FC1);
cvCreateData(M);

//以上两个语句完全等价于以下语句
CvMat* M = cvCreateMat(4, 4, CV_32FC1);



(2)cvCreateMatHeader()
函数创建CvMat结构,不为数据分配内存,而cvCreateData

()函数只负责数据的内存分配。有时,只需要函数cvCreateMatHeader
(),因为已因其他理由分配了存储空间,或因为还不准备分配存储空间。

cvCreateMatHeader

Creates a matrix header but does not allocate the matrix data.

//创建一个矩阵头但是不为矩阵数据分配内存空间

CvMat* cvCreateMatHeader
(

int rows,

int cols,

int type);

rows Number of rows in the matrix

cols Number of columns in the matrix

type Type of the matrix elements, see cvCreateMat

The function allocates a new matrix header and returns a pointer to it. The matrix data can

then be allocated using cvCreateData
or set explicitly to user-allocated data via cvSetData.

cvCreateData

Allocates array data//为数组分配内存空间

void cvCreateData(CvArr* arr);

arr Array header//arr是数组头

The function allocates image, matrix or multi-dimensional array data. Note that in the case

of matrix types OpenCV allocation functions are used and in the case of IplImage they are used

unless CV TURN ON IPL COMPATIBILITY was called. In the latter case IPL functions are used

to allocate the data.

//该函数为图像、矩阵或者多维数组分配内存空间。请注意,当arr是矩阵的时候调用opencv内存分配函数,当arr是图像的时候,除非使用
CV TURN ON IPL COMPATIBILITY也是
调用opencv内存分配函数。后者(就是arr是图像的时候)调用IPL函数进行数据内存的分配。

//Create only matrix header without allocating data
//
CvMat* cvCreateMatHeader( int rows, int cols, int type );


(3)是用函数cvCloneMat (CvMat*)

,它依据一个现有矩阵创建一个新的矩阵。

//Allocate a new matrix just like the matrix 'mat'.
//
CvMat* cvCloneMat( const cvMat* mat );


CvMat* M1 = cvCreateMat(4,4,CV_32FC1);
CvMat* M2;
M2=cvCloneMat(M1);


cvCloneMat

Creates a full matrix copy.//创建一个既有矩阵数据头又有矩阵数据内存空间的矩阵

CvMat* cvCloneMat(const CvMat* mat);

mat Matrix to be copied

Creates a full copy of a matrix and returns a pointer to the copy.

(4)直接定义

//当然该方法不常用,并经熟悉opencv就会知道里面处处是指针,所以一般用
cvCreateMat()

CvMat	mb ;


(5)当创建的矩阵不再需要时,可以调用函数cvReleaseMat(CvMat*)
释放它。

注意
:由上面(4)创建的矩阵不需要调用
cvReleaseMat(CvMat*)
释放它。

// Free the matrix 'mat', both header and data.
//
void cvReleaseMat( CvMat** mat );


二、矩阵的赋值(初始化)

(1)cvInitMatHeader和已有数据进行初始化

//Initialize header on existiong CvMat structure
//
CvMat* cvInitMatHeader(

CvMat* mat,
int   rows,
int   cols,
int   type,
void* data = NULL,
int   step = CV_AUTOSTEP
);


//定为double是不行的,浮点型的话只支持float!!
float arr[] = { 1,2,3,
4,5,6, };
//1.利用已有数据进行初始化
CvMat  ma;
cvInitMatHeader( &ma,2,3,CV_32FC1,arr,CV_AUTOSTEP );


This function is often used to process raw data with OpenCV matrix functions. For example,
the following code computes the matrix product of two matrices, stored as ordinary arrays:
double a[] = { 1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12 };
double b[] = { 1,2,3,4,5,
6,7,8,9,10,11,12 };
double c[9];
CvMat Ma, Mb, Mc ;
cvInitMatHeader(&Ma, 3, 4, CV_64FC1, a);
cvInitMatHeader(&Mb, 4, 3, CV_64FC1, b);
cvInitMatHeader(&Mc, 3, 3, CV_64FC1, c);
cvMatMulAdd(&Ma, &Mb, 0, &Mc);
// the c array now contains the product of a (3x4) and b (4x3)


(2)利用CvMat构造函数进行初始化。

cvMat

Initializes matrix header (lightweight variant).

CvMat cvMat(

int rows,

int cols,

int type,

void* data=NULL);

rows Number of rows in the matrix

cols Number of columns in the matrix

type Type of the matrix elements - see cvCreateMat

data Optional data pointer assigned to the matrix header

Initializes a matrix header and assigns data to it. The matrix is filled row-wise (the first cols

elements of data form the first row of the matrix, etc.)

This function is a fast inline substitution for cvInitMatHeader. Namely, it is equivalent to:

CvMat mat;

cvInitMatHeader(&mat, rows, cols, type, data, CV_AUTOSTEP);

//定为double是不行的,浮点型的话只支持float!!
float arr[] = { 1,2,3,
4,5,6, };
//2.cvInitHeader与cvMat原理几乎都是一样的,只是函数原型不太一样
CvMat	mb ;
mb = cvMat(2,3,CV_32FC1,arr);


三、实战

#include "cv.h"
#include "cxcore.h"
#include <stdio.h>
//打印矩阵的元素
//参考了《学习opencv》一书的例3-9
void print_mat( const CvMat* mat,const int row ,const int col )
{
int i ;
int j ;

//用指针实现了对矩阵元素的访问
for ( i = 0 ; i < row ; i++ )
{
/*uchar* ptr = (uchar*)(mat->data.ptr + i * mat->step);*/
//用uchar就是错的
float* ptr = (float*)( mat->data.ptr + i * mat->step ) ;
for ( j = 0 ; j < col ; j++ )
{
printf("/t%f",ptr[j]);//用*ptr++也可以
}
printf("/n");
}
printf("/n/n");
}
//
int main()
{
//定为double是不行的,浮点型的话只支持float!!
float arr[] = { 1,2,3,
4,5,6, };
//1.利用已有数据进行初始化
CvMat  ma;
cvInitMatHeader( &ma,2,3,CV_32FC1,arr,CV_AUTOSTEP );
//2.cvInitHeader与cvMat原理几乎都是一样的,只是函数原型不太一样
CvMat	mb ;
mb = cvMat(2,3,CV_32FC1,arr);
//3.cvCreateMat返回一个矩阵指针
CvMat* 	mc = cvCreateMat( 2,2,CV_32FC1 );
//cvmGet(...)、cvmSet(...)只对浮点型单通道数据有效
cvmSet(mc,0,0,1);
cvmSet(mc,0,1,2);
cvmSet(mc,1,0,3);
cvmSet(mc,1,1,4);
CvMat* md = cvCreateMat( 3,4,CV_64FC1 );
int i ;
int j ;
int n = 0 ;
//用指针实现了对矩阵元素的访问
for ( i = 0 ; i < 3 ; i++ )
{
float* ptr = (float*)( md->data.ptr + i * md->step ) ;
for ( j = 0 ; j < 4 ; j++ )
{
ptr[j] = ++n ;
}
printf("/n");
}
print_mat( &ma,2,3 );
print_mat( &mb,2,3 );
print_mat( mc,2,2 );
print_mat( md ,3,4);

cvReleaseMat(&mc);
cvReleaseMat(&md);
return 0 ;
}


运行结果:

opencv@ubuntu:~/桌面/opencv$ gcc `pkg-config opencv --libs --cflags opencv`  -g mat.c -o mat
opencv@ubuntu:~/桌面/opencv$ ./mat
1.000000	2.000000	3.000000
4.000000	5.000000	6.000000
1.000000	2.000000	3.000000
4.000000	5.000000	6.000000
1.000000	2.000000
3.000000	4.000000
1.000000	2.000000	3.000000	4.000000
5.000000	6.000000	7.000000	8.000000
9.000000	10.000000	11.000000	12.000000


一个一个字码实在不是容易,怕误人子弟还要参考英文reference。转载请注明出处http://blog.csdn.net/moc062066/archive/2011/06/15/6546612.aspx
。谢谢!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: