Mat 讀取資料 及效率對比

2021-08-21 04:30:13 字數 3018 閱讀 4312

(1) mat::mat()

(2) mat::mat(int rows, int cols, int type)

(3) mat::mat(size size, int type)

(4) mat::mat(int rows, int cols, int type, constscalar&s)

(5) mat::mat(size size, int type, constscalar&s)

(6) mat::mat(const mat& m)

(8) mat::mat(size size, int type, void* data, size_t step=auto_step)

(9) mat::mat(const mat& m, const range& rowrange, const range& colrange)

(10) mat::mat(const mat& m, const rect& roi)

(11) mat::mat(const cvmat* m, bool copydata=false)

(12) mat::mat(const iplimage* img, bool copydata=false)

(13) templateexplicit mat::mat(const vec& vec, bool copydata=true)

(14) templateexplicit mat::mat(const matx& vec, bool copydata=true)

(15) templateexplicit mat::mat(const vector& vec, bool copydata=false)

(16) mat::mat(const matexpr& expr)

(17) mat::mat(int ndims, const int* sizes, int type)

(18) mat::mat(int ndims, const int* sizes, int type, constscalar&s)

(19) mat::mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0)

(20) mat::mat(const mat& m, const range* ranges)

opencv 裡面的很多東西都會涉及到對mat的操作,從基本的單個元素訪問到整個mat 資料的掃瞄。一般情況下用mat.at(point pt)就可以了,但是當有反覆訪問整個mat資料的時候,整個掃瞄的效率就值得考慮了。有些同學對三通道或多通道的mat資料的讀取或許還有些疑問,同時,在debug和release的不同情況下,資料的讀取速度也是不同的。所以這裡再討論一下幾種資料訪問的方法。

1 mat.at 

at 操作可以說是opencv提供的官方操作, 具體執行如:

for (int i = 0; i(i,j);//i是行,j是列,point(x,y),x是列,y是行,注意

color[0] = 0;

color[1] = 255;

color[2] = 255;

}}

用at來掃瞄整個資料確實顯得比較臃腫。估計是因為裡面涉及到很多opencv設定的指標之類的操作,我猜想是有很多需要動態鏈結的東西, 所以整個掃瞄過程比較慢,在debug模式下,會消耗很多時間。但是在release模式下,at操作將會快很多,僅僅比直接用指標的操作慢一點點,所以在真正運用的時候,at的速度並不慢。

2 指標 

mat的資料結構是分為兩部分的,乙個是頭,乙個是資料。頭就相當於很多檔案前面的說明性內容,表明記錄的是什麼,怎麼記錄的,有什麼特點,資料位置在哪之類。而資料就是單純的資料,這個資料占用一串連續的儲存空間。 資料和頭在記憶體中的位置並不是必須連在一起的,但是頭中肯定記錄了資料的位置,這些資料的位置包括整個資料的起始和終點,每一行資料的起始位置等等。資料的儲存順序是按行進行的,從左到右,依次記錄每個位置的所有通道的資料。所以說,只要我們知道了資料的起始位置和資料型別,那麼利用指標就可以很方便快捷的掃瞄整個資料了。 

利用指標讀取資料的方法有三種,第一種是獲取資料的開頭後直接讀取所有資料,資料的讀取就像陣列一樣。這種方法要求頭裡面指定的整個資料必須連續。 像前面說的,一般情況下資料都是連續的,但是有時頭裡面指定的是某幾個資料段,這時資料有可能就不連續。可以利用mat.iscontinuous()來檢視頭裡面指定的資料是否是連續的。具體執行如:

if (img.iscontinuous())//判斷資料是否連續

}

第二種方法是獲取每行資料的起始位置然後利用同樣的原理進行資料的讀取。因為一行內的資料肯定是連續的,所以不用檢測資料是否連續。具體如下:

int channels = img.channels();

int j_end = img.cols*channel;

for (int i = 0; i(i);

for (int j = 0; j在上面鏈結的那篇部落格裡,還介紹了一種指標的掃瞄方式,是利用mat.step來返回每行資料的長度,然後據此來找到所有資料的位置。因為指標的位置是根據資料的開始位置和行數及列數來計算的,所以該方法也要求所有的資料都是連續的。具體如下:

int step = img.step;

int channels= img.channels();

uchar* data;

for (int i = 0; i利用指標來讀取資料是最快的掃瞄方式,無論在debug還是release模式下。 一般情況下,迴圈中的操作越少速度會越快,所以第一種指標讀取的速度是最快的,第二種涉及到讀取每行的資料位置,速度稍慢一點,最後一種涉及到兩個乘法,所以更慢一些。但是經過多次測試,這三種指標的讀取速度都比mat.at的速度要快一點。

總結:對mat型別的資料的讀取在一般情況下用at操作就可以了,但當涉及反覆讀取整個資料即需要多次掃瞄資料的時候,指標是比較高效的方法。好的程式設計風格確實可以極大提公升程式的準確率和速度,節約程式設計師的時間。 在迴圈中盡量少涉及複雜的計算,特別是一些可以避免的重複計算。

windows檔案讀取效率對比

readfile1.cpp是使用記憶體對映檔案讀取檔案,readfile2.cpp是普通readfile readfile1.cpp char buf 10001 const char env getenv data dir char wsp 255 sprintf wsp,s demo.dbf e...

c 反射用法及效率對比

反射例項化類 通過反射例項化物件,要比直接 new 要慢 50 倍左右 assembly.createinstance 要比 activator.createinstance 慢,主要的效能損耗在 assembly.gettype 反射呼叫類的方法 class program static void...

Raw資料讀取以及轉換為Mat

raw的原意就是 未經加工 可以理解為 raw影象就是cmos或者ccd影象感應器將捕捉到的光源訊號轉化為數碼訊號的原始資料。raw檔案是一種記錄了數位相機感測器的原始資訊,同時記錄了由相機拍攝所產生的一些元資料 metadata,如iso的設定 快門速度 光圈值 白平衡等 的檔案。raw是未經處理...