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("\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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM