• OpenCV中CvMat的初始化[转]


    一)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("
    ");
    	}
    	printf("
    ");
    
    	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("
    ");
    	}
    	printf("
    ");
    
    	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("
    ");
    	}
    	printf("
    ");
    
    	//再次使用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("
    ");
    	}
    	printf("
    ");
    
    	//使用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("
    ");
    	}
    	printf("
    ");
    
    	//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	",*p,*(p+1),*(p+2));
            p+=3;
            if((i+1) % 3 == 0)
                printf("
    ");
        }
    }
    


    五)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("
    ");
    	}
    	printf("
    ");
    
    	//再次使用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("
    ");
    	}
    	printf("
    ");
    
    	//使用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("
    ");
    	}
    	printf("
    ");
    
    	//cvReleaseData可以使CvMat::data.ptr置为NULL
    	//不能调用cvReleaseMat,因cvInitMatHeader未给CvMat分配数据
    	cvReleaseData(&m);
    
    	return 0;
    }
  • 相关阅读:
    leetcode 763 划分字母区间
    leetcode 392 判断子序列
    Leetcode 665 修改一个数成为非递减数组 (Easy)
    leetcode 605 种花问题 贪心算法
    leetcode 452 用最少数量的箭引爆气球 贪心算法
    leetcode 455 分发饼干 贪心算法
    delphi中的 CLX Application
    delphi 之DCOM应用服务器定义函数
    SqlServer 之 sp_executesql系统存储过程的介绍和使用
    delphi 之调用WinSock的API获取本机的机器名称和IP地址
  • 原文地址:https://www.cnblogs.com/xingrun/p/3404436.html
Copyright © 2020-2023  润新知