一)cvCreateMat创建和分配数据
CvCreateMat会创建CvMat,并为CvMat分配数据。cvCreateMat可以配合cvInitMatHeader来初始化CvMat对象。
因为CvCreateMat创建的CvMat,对象在堆上,数据也在堆上,所以cvInitMatHeader在指定新的数据所在的位置的同时,也将CvMat::hdr_refcount和CvMat::refcount都置为0,以便cvReleaseMat释放CvMat对象和数据。

#include <cv.h>
#include <stdio.h>
int main()
{
double a[9]={1,2,3,4,5,6,7,8,9};
double* data=0; CvMat *pm=cvCreateMat(3,3,CV_64FC1);
cvInitMatHeader(pm,3,3,CV_64FC1,a);
data=pm->data.db;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
printf("%3.lf",data[i*3+j]);
}
printf("\n");
}
printf("\n"); cvReleaseData(pm);
cvReleaseMat(&pm); return 0;
}

二)cvCreateMatHeader创建
cvCreateMatHeader只会创建CvMat,不会为CvMat分配数据。cvCreateMatHeader可以配合cvInitMatHeader来初始化CvMat对象。
因为cvCreateMatHeader创建的CvMat,对象在堆上,所以cvInitMatHeader在指定新的数据所在的位置的同时,也将CvMat::hdr_refcount置为0,以便cvReleaseMat释放CvMat对象和数据。

#include <cv.h>
#include <stdio.h>
int main()
{
double a[9]={1,2,3,4,5,6,7,8,9};
double* data=0; CvMat *pm=cvCreateMatHeader(3,3,CV_64FC1);
cvInitMatHeader(pm,3,3,CV_64FC1,a);
data=pm->data.db;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
printf("%3.lf",data[i*3+j]);
}
printf("\n");
}
printf("\n"); cvReleaseData(pm);
cvReleaseMat(&pm); return 0;
}

三)cvMat创建和初始化
cvMat可以视作是CvMat的构造函数,它是一个内联函数。cvMat可以为CvMat指定数据所在的位置。

cvMat在栈上创建CvMat,所以CvMat::hdr_refcount置为0。cvMat并未给CvMat分配数据(在堆上),而是直接传入已经创建好的数据(在堆上或在栈上),所以CvMat::refcount置为NULL。正因为前面两者,可以为一个CvMat变量多次使用cvMat(还可以使用cvInitMatHeader)而不用考虑内存泄露,最后用cvReleaseData释放堆上创建的CvMat对象,或称为矩阵头对象就可以了。

这一初始化方式类似于CvSize等的构造方式,只不过比它们复杂些(传入参数多且需要cvReleaseData来释放堆上创建的CvMat对象)。

cvMat和cvCreateMatHeader都是初始化CvMat头,都没有分配数据。他们的区别在于:
1)cvMat在栈上创建CvMat,cvCreateMatHeader在堆上创建CvMat
2)cvMat内头引用数置为0,cvCreateMatHeader内头引用数置为1。
3)cvMat可以指定数据所在位置,cvCreateMatHeader不能。
4)cvMat是内联函数,cvCreateMatHeader的错误处理机制更完善。

#include <cv.h>
#include <stdio.h>
int main()
{
double a[9]={1,2,3,4,5,6,7,8,9};
double b[6]={6,5,4,3,2,1};
double c[4]={4,3,2,1};
double* data=0; CvMat m=cvMat(3,3,CV_64FC1,a);
data=m.data.db;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
printf("%3.lf",data[i*3+j]);
}
printf("\n");
}
printf("\n"); //再次使用cvMat
m=cvMat(2,3,CV_64FC1,b);
data=m.data.db;
for(int i=0;i<2;i++)
{
for(int j=0;j<3;j++)
{
printf("%3.lf",data[i*3+j]);
}
printf("\n");
}
printf("\n"); //使用cvMatcvInitMatHeader
cvInitMatHeader(&m,2,3,CV_64FC1,c,CV_AUTOSTEP);
data=m.data.db;
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
printf("%3.lf",data[i*2+j]);
}
printf("\n");
}
printf("\n"); //cvReleaseData可以使CvMat::data.ptr置为NULL
//不能调用cvReleaseMat,因cvMat未给CvMat分配数据
cvReleaseData(&m); return 0;
}

四)直接初始化

#include "cxcore.h"
#include <stdio.h>
void main()
{
CvMat* mat = cvCreateMat(3,3,CV_32FC3);
cvZero(mat); float *p = (float*)cvPtr2D(mat, 0, 0);
for(int i = 0; i < 9; i++)
{
*p = (float)i*10;
p++;
*p = (float)i*10+1;
p++;
*p = (float)i*10+2;
p++;
} p = (float*)cvPtr2D(mat, 0, 0); for(i = 0; i < 9; i++)
{
printf("%2.1f,%02.1f,%2.1f\t",*p,*(p+1),*(p+2));
p+=3;
if((i+1) % 3 == 0)
printf("\n");
}
}

五)cvInitMatHeader初始化
cvInitMatHeader并不创建CvMat对象,这个对象由用户创建(在堆上或栈上)并传入。cvInitMatHeader也不创建数据,也是作为参数传入。cvInitMatHeader利用传入的数据等参数初始化这个用户传入的CvMat

CvMat::hdr_refcount被置为0,不管传入的CvMat对象在堆上创建还是在栈上创建。CvMat::refcount被置为NULL,不管数据是否创建或指定。cvInitMatHeader可以为CvMat指定新的数据所在的位置。可以为一个CvMat变量多次使用cvInitMatHeader(还可以使用cvMat)。

cvInitMatHeader与cvMat和cvCreateMatHeader的最大区别在于前者不创建CvMat对象,后者创建CvMat对象。
cvInitMatHeader可以独立,也可以配合cvCreateMatHeader和cvCreateMat,来初始化CvMat

#include <cv.h>
#include <stdio.h>
int main()
{
double a[9]={1,2,3,4,5,6,7,8,9};
double b[6]={6,5,4,3,2,1};
double c[4]={4,3,2,1};
double* data=0; CvMat m;
cvInitMatHeader(&m,3,3,CV_64FC1,a);
data=m.data.db;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
printf("%3.lf",data[i*3+j]);
}
printf("\n");
}
printf("\n"); //再次使用cvInitMatHeader
cvInitMatHeader(&m,3,3,CV_64FC1,b);
data=m.data.db;
for(int i=0;i<2;i++)
{
for(int j=0;j<3;j++)
{
printf("%3.lf",data[i*3+j]);
}
printf("\n");
}
printf("\n"); //使用cvMat
m=cvMat(2,2,CV_64FC1,a);
data=m.data.db;
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
printf("%3.lf",data[i*2+j]);
}
printf("\n");
}
printf("\n"); //cvReleaseData可以使CvMat::data.ptr置为NULL
//不能调用cvReleaseMat,因cvInitMatHeader未给CvMat分配数据
cvReleaseData(&m); return 0;
}

OpenCV中CvMat的初始化[转]的更多相关文章

  1. OpenCV中IplImage/CvMat/Mat转化关系

    原文链接:http://www.cnblogs.com/summerRQ/articles/2406109.html 如对内容和版权有何疑问,请拜访原作者或者通知本人. opencv中常见的与图像操作 ...

  2. opencv中Mat与IplImage,CVMat类型之间转换

    opencv中对图像的处理是最基本的操作,一般的图像类型为IplImage类型,但是当我们对图像进行处理的时候,多数都是对像素矩阵进行处理,所以这三个类型之间的转换会对我们的工作带来便利. Mat类型 ...

  3. OpenCV 中的三大数据类型:CvMat 类型

    前言 本文将介绍 OpenCV 中的矩阵结构 CvMat 并提供几个很常用的矩阵使用方法. 更多的矩阵处理函数还请参阅相关资料. CvMat 的类型定义 typedef struct CvMat { ...

  4. OpenCV中对Mat里面depth,dims,channels,step,data,elemSize和数据地址计算的理解 (转)

    cv::Matdepth/dims/channels/step/data/elemSizeThe class Mat represents an n-dimensional dense numeric ...

  5. OpenCV中的矩阵和图像类型

    任务刚刚做完,就迫不及待的来写写在OpenCV中常见的几类数据类型: 在使用OpenCV时我们时常会碰到IplImage这个数据类型,IplImage就是我们通常说的“图像”进行编码的基本结构,这些图 ...

  6. OpenCV之CvMat、Mat、IplImage之间相互转换实例(转)

    OpenCV学习之CvMat的用法详解及实例 CvMat是OpenCV比较基础的函数.初学者应该掌握并熟练应用.但是我认为计算机专业学习的方法是,不断的总结并且提炼,同时还要做大量的实践,如编码,才能 ...

  7. Opencv中SVM样本训练、归类流程及实现

    支持向量机(SVM)中最核心的是什么?个人理解就是前4个字--"支持向量",一旦在两类或多累样本集中定位到某些特定的点作为支持向量,就可以依据这些支持向量计算出来分类超平面,再依据 ...

  8. 解析opencv中Box Filter的实现并提出进一步加速的方案(源码共享)。

    说明:本文所有算法的涉及到的优化均指在PC上进行的,对于其他构架是否合适未知,请自行试验. Box Filter,最经典的一种领域操作,在无数的场合中都有着广泛的应用,作为一个很基础的函数,其性能的好 ...

  9. 混合高斯模型:opencv中MOG2的代码结构梳理

    /* 头文件:OurGaussmix2.h */ #include "opencv2/core/core.hpp" #include <list> #include&q ...

随机推荐

  1. bzoj 4711 小奇挖矿 ——“承诺”类树形dp

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4711 对“承诺”有了更深的了解. 向外和向内要区分,所以 f [ i ][ j ] 表示根向 ...

  2. 《Linux内核修炼之道》精华分享与讨论(5)——Kernel地图:Kconfig与Makefile

    转自:http://blog.csdn.net/fudan_abc/article/details/5340408 Makefile不是Make Love 从前在学校,混了四年,没有学到任何东西,每天 ...

  3. Outlook 开发2

    转自:http://www.cnblogs.com/madebychina/archive/2011/09/20/madebychina_2.html C#使用如下代码调用Outlook2003发送邮 ...

  4. mfc画波形函数

    void CMyPicoTestDlg::DrawWave(CDC *pDC,CRect &rectPicture) { float fDeltaX; float fDeltaY; int n ...

  5. 堆栈(栈stack)的实现和基本用法(二)

    个人网站http://www.ravedonut.com/ 栈的应用: #include <iostream> #include <stack> using namespace ...

  6. Hadoop中Yarnrunner里面submit Job以及AM生成 至Job处理过程源码解析

    参考 http://blog.csdn.net/caodaoxi/article/details/12970993 Hadoop中Yarnrunner里面submit Job以及AM生成 至Job处理 ...

  7. HUD-1548

    A strange lift Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  8. 【网络爬虫】【python】网络爬虫(一):python爬虫概述

    python爬虫的实现方式: 1.简单点的urllib2 + regex,足够了,可以实现最基本的网页下载功能.实现思路就是前面java版爬虫差不多,把网页拉回来,再正则regex解析信息--总结起来 ...

  9. TP5之发送邮件

    1.下载扩展,vendor\phpmailer 文件结构: 2.话不多说,上代码    注意点: ·   需要提前开通对应邮箱的SMTP服务 ·  $mail->Host = "  & ...

  10. 5-2 Windows消息队列 (25分)

    5-2 Windows消息队列   (25分) 消息队列是Windows系统的基础.对于每个进程,系统维护一个消息队列.如果在进程中有特定事件发生,如点击鼠标.文字改变等,系统将把这个消息加到队列当中 ...