CvMat矩阵数据结构

2024-05-08 10:18
文章标签 数据结构 矩阵 cvmat

本文主要是介绍CvMat矩阵数据结构,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


      当我们学习CvMat之前,OpenCV中矩阵的概念比线性代数中矩阵的概念更抽象和复杂一些一些。例如,创建矩阵的函数:CvMat*cvCreateMat(int rows,int cols,inttype),其中type代表预定义的数据类型,即矩阵中每一个元素的数据类型, 该类型的形式是:CV_<bit数>(S|U|F)C<通道数>,例如,数据类型可能是CV32FC1,即32bit的浮点数,或CV_8UC3,8bit的无符号整数,或CV_8UC3,无符号8bit整数,3通道,等等。我们会发现,cvMat里,矩阵中行和列上的每一个元素,不必是一个单独的数字,可能是一系列数字 (有几个通道就有几个数字)。每一个元素可以代表多个值,就允许了我们在矩阵中包含一个RGB的图像。
从内部的结构上看,CvMat相当的简单,我们可以通过代码看一下该数据结构的原型(代码在.../opencv/cxcore/include/cxtypes.h):
其中包含了width,height,type,step(是一行元素的长度,与width类似,但以字节计算),以及指向数据的指针。你可以通过CvMat数据类型的变量直接接触该类型内部的成员,例如,CvMat* matrix,就可以用matrix->height,matrix->width来获得矩阵的尺寸。又或者通过OpenCV的函数来获得。例如,可以用cvGetSize(CvMat*)来获得CvSize对象,这代表该矩阵的长和宽。
typedef struct CvMat
{
int type;
int step;


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类型的数据的“头部”,即矩阵的定义部分。许多OpenCV的函数,将矩阵的头部和数据部分分开处理。
矩阵的创建可以用多种方法,最简单的一种是CvMat* cvCreateMat(int rows,int cols,inttype),该方法既设置了矩阵的头部,又为数据部分分配了内存空间,该函数是cvCreateMatHeader()和cvCreateData()的合并缩写。cvCreateMatHeader()只创建CvMat头部,但不为数据部分分配空间。而cvCreateData()则是为矩阵的数据部分分配了内存空间。有时候,我们只需要cvCreateMatHeader()就可以了,因为基于一些理由,我们可能已经为数据部分分配了空间,或者此时分配空间还不是时候。另一个创建矩阵的方法cvCloneMat(CvMat*)是从一个已经有的矩阵,来“克隆”出一个新的矩阵来。当我们不再需要某矩阵时,我们需要调用cvReleaseMat(CvMat*)来释放它。
就象其他的OpenCV数据类型一样,矩阵数据类型有一个构造函 数,CvMat cvMat( int rows, int cols,int type, void* data=NULL);这个函数没有为矩阵的数据部分分配空间,只是初始化了矩阵的头部,类似cvInitMatheader()。

以下是这些函数的原型:
1,CreateMat
创建矩阵
CvMat* cvCreateMat( int rows, int cols, int type );
rows
矩阵行数。
cols
矩阵列数。
type
矩阵元素类型。
通常以CV_<比特数>(S|U|F)C<通道数>型式描述,例如:
CV_8UC1 意思是一个8-bit 无符号单通道矩阵,CV_32SC2 意思是一个32-bit 有符号二个通道的矩阵。

函数 cvCreateMat 为新的矩阵分配头和下面的数据,并且返回一个指向新创建的矩阵的指针。是下列操作的缩写型式:
CvMat* mat = cvCreateMatHeader( rows, cols, type );
cvCreateData( mat );
矩阵按行存贮。所有的行以4个字节对齐。

2,CreateMatHeader
创建新的矩阵头
CvMat* cvCreateMatHeader( int rows, int cols, int type );
rows
矩阵行数.
cols
矩阵列数.
type
矩阵元素类型(见 cvCreateMat).

函数 cvCreateMatHeader 分配新的矩阵头并且返回指向它的指针,矩阵数据可被进一步的分配,使用cvCreateData或通过 cvSetData明确的分配数据。

3,ReleaseMat
删除矩阵
void cvReleaseMat( CvMat** mat );
mat
双指针指向矩阵.

函数cvReleaseMat 缩减矩阵数据参考计数并且释放矩阵头 :
if( *mat )
cvDecRefData( *mat );
cvFree( (void**)mat );

4,InitMatHeader
初始化矩阵头
CvMat* cvInitMatHeader( CvMat* mat, int rows, int cols, inttype,
void* data=NULL, int step=CV_AUTOSTEP );
mat
指针指向要被初始化的矩阵头.
rows
矩阵的行数.
cols
矩阵的列数.
type
矩阵元素类型.
data
可选的,将指向数据指针分配给矩阵头.
step
排列后的数据的整个行宽,默认状态下,使用STEP的最小可能值。也就是说默认情况下假定矩阵的行与行之间无隙.

函数 cvInitMatHeader 初始化已经分配了的 CvMat 结构。它可以被OpenCV矩阵函数用于处理原始数据。
例如,下面的代码计算通用数组格式存贮的数据的矩阵乘积。

计算两个矩阵的积

double a[] = { 1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12 };

double b[] = { 1, 5, 9,
2, 6, 10,
3, 7, 11,
4, 8, 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 );
// c 数组存贮 a(3x4) 和 b(4x3) 矩阵的积

5,Mat
初始化矩阵的头
CvMat cvMat( int rows, int cols, int type, void* data=NULL );
rows
矩阵行数
cols
列数.
type
元素类型(见CreateMat).
data
可选的分配给矩阵头的数据指针 .

函数 cvMat 是个一快速内连函数,替代函数 cvInitMatHeader. 也就是说它相当于:
CvMat mat;
cvInitMatHeader( &mat, rows, cols, type, data,CV_AUTOSTEP );

6,CloneMat
创建矩阵拷贝
CvMat* cvCloneMat( const CvMat* mat );
mat
输入矩阵.

函数 cvCloneMat 创建输入矩阵的一个拷贝并且返回该矩阵的指针。

以下的例子中,我们让矩阵的数据部分指向了已经分配好了的数据:
float vals[] = { 0.866025, -0.500000, 0.500000, 0.866025};
CvMat rotmat;
cvInitMatHeader(
&rotmat,
2,
2,
CV_32FC1,
vals
);

当我们定义好了矩阵,我们可以通过一些函数查看矩阵的属性,例如:cvGetElemType(const cvArr*arr),cvGetDims(const CvArr* arr,int* sizes=NULL),cvGetDimSize(constCvArr* arr,index)


这篇关于CvMat矩阵数据结构的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/970046

相关文章

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

hdu 4565 推倒公式+矩阵快速幂

题意 求下式的值: Sn=⌈ (a+b√)n⌉%m S_n = \lceil\ (a + \sqrt{b}) ^ n \rceil\% m 其中: 0<a,m<215 0< a, m < 2^{15} 0<b,n<231 0 < b, n < 2^{31} (a−1)2<b<a2 (a-1)^2< b < a^2 解析 令: An=(a+b√)n A_n = (a +

《数据结构(C语言版)第二版》第八章-排序(8.3-交换排序、8.4-选择排序)

8.3 交换排序 8.3.1 冒泡排序 【算法特点】 (1) 稳定排序。 (2) 可用于链式存储结构。 (3) 移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时, 此算法不宜采用。 #include <stdio.h>#include <stdlib.h>#define MAXSIZE 26typedef int KeyType;typedef char In

hdu 6198 dfs枚举找规律+矩阵乘法

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description We define a sequence  F : ⋅   F0=0,F1=1 ; ⋅   Fn=Fn

【408数据结构】散列 (哈希)知识点集合复习考点题目

苏泽  “弃工从研”的路上很孤独,于是我记下了些许笔记相伴,希望能够帮助到大家    知识点 1. 散列查找 散列查找是一种高效的查找方法,它通过散列函数将关键字映射到数组的一个位置,从而实现快速查找。这种方法的时间复杂度平均为(

浙大数据结构:树的定义与操作

四种遍历 #include<iostream>#include<queue>using namespace std;typedef struct treenode *BinTree;typedef BinTree position;typedef int ElementType;struct treenode{ElementType data;BinTree left;BinTre

Python 内置的一些数据结构

文章目录 1. 列表 (List)2. 元组 (Tuple)3. 字典 (Dictionary)4. 集合 (Set)5. 字符串 (String) Python 提供了几种内置的数据结构来存储和操作数据,每种都有其独特的特点和用途。下面是一些常用的数据结构及其简要说明: 1. 列表 (List) 列表是一种可变的有序集合,可以存放任意类型的数据。列表中的元素可以通过索

浙大数据结构:04-树7 二叉搜索树的操作集

这道题答案都在PPT上,所以先学会再写的话并不难。 1、BinTree Insert( BinTree BST, ElementType X ) 递归实现,小就进左子树,大就进右子树。 为空就新建结点插入。 BinTree Insert( BinTree BST, ElementType X ){if(!BST){BST=(BinTree)malloc(sizeof(struct TNo

【数据结构入门】排序算法之交换排序与归并排序

前言         在前一篇博客,我们学习了排序算法中的插入排序和选择排序,接下来我们将继续探索交换排序与归并排序,这两个排序都是重头戏,让我们接着往下看。  一、交换排序 1.1 冒泡排序 冒泡排序是一种简单的排序算法。 1.1.1 基本思想 它的基本思想是通过相邻元素的比较和交换,让较大的元素逐渐向右移动,从而将最大的元素移动到最右边。 动画演示: 1.1.2 具体步