2.1(OpenCV核心類型Mat)-Mat解析

關於 Mat ,首先要知道的是你不必再手動地

(1)爲其開闢空間

(2)在不需要時立即將空間釋放

但手動地做還是可以的:大多數OpenCV函數仍會手動地爲輸出數據開闢空間。當傳遞一個已經存在的 Mat 對象時,開闢好的矩陣空間會被重用。也就是說,我們每次都使用大小正好的內存來完成任務。

MatOpenCV裏最基本的一個類,由兩個數據部分組成:矩陣頭(包含矩陣尺寸,存儲方法,存儲地址等信息)和一個指向存儲矩陣所有像素值的指針。矩陣頭的尺寸是常數值,但矩陣本身的尺寸會依圖像的不同而不同,通常比矩陣頭的尺寸大數個數量級。因此,當在程序中傳遞圖像並創建拷貝時,大的開銷是由矩陣造成的,而不是信息頭。OpenCV是一個圖像處理庫,囊括了大量的圖像處理函數,爲了解決問題通常要使用庫中的多個函數,因此在函數中傳遞圖像是家常便飯。同時不要忘了我們正在討論的是計算量很大的圖像處理算法,因此,除非萬不得已,我們不應該拷貝大的圖像,因爲這會降低程序速度。

爲了搞定這個問題,OpenCV使用引用計數機制。其思路是讓每個 Mat 對象有自己的信息頭,但共享同一個矩陣。這通過讓矩陣指針指向同一地址而實現。而拷貝構造函數則只拷貝信息頭和矩陣指針,而不拷貝矩陣

 

Mat A, C;                                 // 只創建信息頭部分

A =imread(argv[1], CV_LOAD_IMAGE_COLOR); // 這裏爲矩陣開闢內存

Mat B(A);                                 // 使用拷貝構造函數

C = A;                                    // 賦值運算符

 

以上代碼中的所有Mat對象最終都指向同一個也是唯一一個數據矩陣。雖然它們的信息頭不同,但通過任何一個對象所做的改變也會影響其它對象。實際上,不同的對象只是訪問相同數據的不同途徑而已。


如果現有成員,後面才能確定參數:

mat.creat(rows,cols, CV_8UC1);


這裏還要提及一個比較棒的功能:你可以創建只引用部分數據的信息頭。比如想要創建一個感興趣區域( ROI,你只需要創建包含邊界信息的信息頭:

 

Mat D (A, Rect(10,10, 100, 100) ); // using a rectangle

Mat E =A(Range:all(), Range(1,3)); // using row and column boundaries

 

現在你也許會問,如果矩陣屬於多個  Mat  對象,那麼當不再需要它時誰來負責清理?簡單的回答是:最後一個使用它的對象。通過引用計數機制來實現。無論什麼時候有人拷貝了一個  Mat  對象的信息頭,都會增加矩陣的引用次數;反之當一個頭被釋放之後,這個計數被減一;當計數值爲零,矩陣會被清理。但某些時候你仍會想拷貝矩陣本身(不只是信息頭和矩陣指針),這時可以使用函數  clone()  或者  copyTo() 。

Mat F = A.clone();

Mat G;

A.copyTo(G);

現在改變 F 或者 G 就不會影響 Mat 信息頭所指向的矩陣。總結一下,你需要記住的是

OpenCV函數中輸出圖像的內存分配是自動完成的(如果不特別指定的話)

使用OpenCVC++接口時不需要考慮內存釋放問題

賦值運算符和拷貝構造函數( ctor)只拷貝信息頭

使用函數 clone() 或者 copyTo() 來拷貝一副圖像的矩陣


對於二維多通道圖像,首先要定義其尺寸,即行數和列數,然後,需要指定存儲元素的數據類型以及每個矩陣點的通道數。爲此,依據下面的規則有多種定義

CV_[The number of bits peritem][Signed or Unsigned][Type Prefix]C[The channel number]

CV_<bit_depth>(S|U|F)C<number_of_channels>

         ①bit_depth

                   比特數---代表8bite,16bites,32bites,64bites

                   舉個例子:

                            如果你現在創建了一個存儲--灰度圖片的Mat對象,這個圖像的大小爲寬100,高100,那麼,現在這張灰度圖片中有10000個像素點,它每一個像素點在內存空間所佔的空間大小是8bite,8位--所以它對 應的就是CV_8

         ②S|U|F

                   S--代表---signedint---有符號整形

                   U--代表--unsignedint--無符號整形

                   F--代表--float---------單精度浮點型

         ③C<number_of_channels>----代表---一張圖片的通道數,比如:

                   1--灰度圖片--grayImg---是--單通道圖像

                   2--RGB彩色圖像---------是--3通道圖像

                   3--帶Alph通道的RGB圖像--是--4通道圖像

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章