簡單的CvMat標頭的製作
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
int main()
{
CvMat *Matrix1=cvCreateMatHeader(10,10,CV_32FC1);
cvCreateData(Matrix1);
cvRange(Matrix1,30,130);
for(int i=0;i<10;i++)
{
for(int j=0;j<10;j++)
{
printf("%.f ",cvGet2D(Matrix1,i,j).val[0]);
}
printf("\n");
}
system("pause");
cvReleaseMatHeader(
&
Matrix1);}
執行結果:
這邊用到的CvMat矩陣的標頭資訊,跟前面IplImage差不多,先用cvCreateMatHeader()創立標頭資訊及標頭空間,再用cvCrateData()創立矩陣空間,而cvCreateMat()就是等於cvCreateMatHeader()+cvCreateData(),只不過這邊用分開的方式創立了空間,cvRange()則是只能用在單通道float型別的CvMat矩陣結構上使用,功能是在做矩陣空間範圍內數據的增加,這邊創立了一個100*100的矩陣,而數據由30加到了130,再用cvGet2D()展示執行結果.
CvMat標頭檔製作2
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
float data[4][8];
int main()
{
CvMat *Matrix1=cvCreateMatHeader(4,8,CV_32FC1);
CvMat Matrix2;
cvSetData(Matrix1,data,Matrix1->step);
cvSet(Matrix1,cvRealScalar(30.1));
cvInitMatHeader(
&
Matrix2,4,4,CV_32FC2,NULL,CV_AUTOSTEP);cvReshape(Matrix1,
&
Matrix2,2,4);for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf("(%.1f,%.1f) ",cvGet2D(
&
Matrix2,i,j).val[0],cvGet2D(&
Matrix2,i,j).val[1]);}
printf("\n");
}
system("pause");
cvReleaseMatHeader(
&
Matrix1);free(
&
Matrix2); }
執行結果:
上面的程式碼,則是標頭資訊的應用之一,兩個資料空間大小相同的矩陣,改變了它列跟欄以及通道的形狀,這邊是用到4(rows)*8(cols)*1(channel)的矩陣,改變成4(rows)*4(cols)*2(channels)的矩陣,利用標頭資訊的內容控制改變它的矩陣空間數據的形狀,因此,資料的排列就因此變形了,主要是用在兩個相同空間大小的矩陣的變換.這邊先用cvCreateMatHeader()創立一個float型別4*8矩陣通道一的標頭資訊,用cvSetData()設立矩陣資料空間,用vInitMatHeader()初始化Matrix2標頭資訊,為float型別4*4通道一的矩陣,接著用cvReshape()改變它的形狀,cvReshape()第三個引數是通道數,第四個引數則是列(rows)的數目.
cvCreateMatHeader()
創立CvMat資料結構的標頭空間及標頭資訊,這邊使用cvCreateMatHeader()後矩陣的資料空間仍為空.
cvCreateMatHeader(矩陣列數(rows)數據,矩陣欄(colunms)數數據,Cvmat資料結構參數)
cvRange()
遞增範圍數據,再矩陣內做範圍遞增的動作,必須用到float型別單通道浮點數的矩陣,第一個引數為目標結構,可為IplImage及CvMat結構,第二個引數為遞增開始值數據,第三個引數為遞增結束值數據.
cvRange(目標IplImage資料結構或CvMat資料結構,開始值數據,結束值數據)
cvInitMatHeader()
初始化矩陣標頭資訊,不包含CvMat標頭空間的創立,跟cvMat()差不多,但cvMat()包含矩陣空間的創立,第一個引數為選擇CvMat資料結構,第二個為列數(rows),第三個為欄數(colunms),第四個為CvMat資料結構矩陣參數,第五個為預設矩陣資料空間,再來是自動設立它的總寬度,由CV_AUTOSTEP則可以自動去計算它的總寬度.
cvInitMatHeader(CvMat資料結構,列數數據,欄數數據,CvMat結構參數,資料空間輸入,CV_AUTOSTEP);
cvReshape()
改變矩陣空間的形狀,為CvMat資料結構特有的函式,第一個引述為要改變的結構空間,可為IplImage及CvMat,第二個引數為輸出值,必須輸入CvMat的標頭資訊,第三個引數為改變通道數,第四個引數為改變的列數(rows).
cvReshape(IplImage資料結構或CvMat資料結構,CvMat標頭資訊,改變的通道數據,改變的列數據)
cvReleaseMatHeader()
釋放CvMat標頭記憶體空間,這邊cvReleaseMatHeader()被定義為
#define cvReleaseMatHeader cvReleaseMat
因此它跟cvReleaseMat()是一樣的.
cvReleaseMatHeader(CvMat標頭資料結構)
4 意見:
你好,我想請問一下
cvMat Matrix2;
cvInitMatHeader(&Matrix2,4,4,CV_32FC2,NULL,CV_AUTOSTEP);
為什麼要宣靠成這樣而不是cvMat *Matrix2呢?
另外,cvInitMatHeader()初始化矩陣標頭資訊,不包含CvMat標頭空間的創立,那第五個引數(資料空間輸入)如果有設值或者矩陣給它,會有整個完成的Mat資訊嗎?
謝謝,看您的文章對學習openCV實在幫助很大 : )
cvMat *Matrix1; <--未給空間
cvMat Matrix2; <--已經配置一段空間
cvInitMatHeader()是直接給數值未做資料結構初始化,所以說給一個沒創立空間的Matrix1會出錯,但是,如果有用cvCreateMat()就會是正確的~
用Matrix2這種方式的好處,可以避免Memory leak,將同樣的變數一直用cvCreateMat()不斷的創造新的記憶體空間而忘了release,倒不如直接用cvMat Matrix2;這種方式來的安全,
第二個問題~ 是的XD,不過cvInitMatHeader(&Matrix2,4,4,CV_32FC1,Array,CV_AUTOSTEP);
的函式呼叫如果給int Array[2][8];
的矩陣,它還是會視為4*4的矩陣,因為他裡面是用Matrix2.step的方式來計算矩陣跳躍的空間
void cvRange( CvArr* mat, double start, double end );
mat
The matrix to initialize. It should be single-channel 32-bit, integer or floating-point.
单通道32位整形也可以用cvRange
恩~差不多瞭解你的意思了,謝謝 :D
張貼留言