一、數字圖像存儲概述
數字圖像存儲時,我們存儲的是圖像每個像素點的數值,對應的是一個數字矩陣。
二、Mat的存儲
1、OpenCV1基於C接口定義的圖像存儲格式IplImage*,直接暴露內存,如果忘記釋放內存,就會造成內存泄漏。
2、從OpenCV2開始,開始使用Mat類存儲圖像,具有以下優勢:
(1)圖像的內存分配和釋放由Mat類自動管理
(2)Mat類由兩部分數據組成:矩陣頭(包含矩陣尺寸、存儲方法、存儲地址等)和一個指向存儲所有像素值的矩陣(根據所選存儲方法的不同,矩陣可以是不同的維數)的指針。Mat在進行賦值和拷貝時,只復制矩陣頭,而不復制矩陣,提高效率。如果矩陣屬於多個Mat對象,則通過引用計數來判斷,當最后一個使用它的對象,則負責釋放矩陣。
(3)可以使用clone和copyTo函數,不僅復制矩陣頭還復制矩陣。
三、Mat創建
1、使用Mat構造函數
Mat test(2,2,CV_8UC3,Scalar(0,0,255));
2、使用Mat構造函數2
int sizes[3] = {2,2,2};
Mat test(3,sizes,CV_8UC3,Scalar::all(0));
3、為已存在的IplImage指針創建信息頭
IplImage* img = cvLoadImage("1.jpg",1);
Mat test(img);
4、利用create函數
Mat test;
test.create(4,4,CV_8UC2);
5、采用Matlab形式的初始化方式
(1)Mat me = Mat::eye(4,4,CV_64F);
(2)Mat mo = Mat::ones(2,2,CV_32F);
(3)Mat mz = Mat::zeros(3,3,CV_8UC1);
注:元素類型,即CV_[位數][帶符號與否][類型前綴]C[通道數]
四、Mat中相關成員的意義
1、data
Mat對象中的一個指針,指向存放矩陣數據的內存(uchar* data)
2、dims
矩陣的維度,3*4的矩陣維度為2維,3*4*5的矩陣維度為3維
3、channels
矩陣通道,矩陣中的每一個矩陣元素擁有的值的個數,比如說 3 * 4 矩陣中一共 12 個元素,如果每個元素有三個值,那么就說這個矩陣是 3 通道的,即 channels = 3。常見的是一張彩色圖片有紅、綠、藍三個通道。
4、depth
深度,即每一個像素的位數,也就是每個通道的位數。在opencv的Mat.depth()中得到的是一個0 – 6的數字,分別代表不同的位數:enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 },可見 0和1都代表8位, 2和3都代表16位,4和5代表32位,6代表64位。
5、elemSize
矩陣中每個元素的大小,每個元素包含channels個通道。如果Mat中的數據的數據類型是CV_8U那么elemSize = 1;是CV_8UC3那么elemSize = 3,是CV_16UC2那么elemSize = 4。
6、elemSize1
矩陣中數據類型的大小,即elemSize/channels,也就是depth對應的位數。
7、step
是一個數組,定義了矩陣的布局,參考下圖


若矩陣有n維,則step數組大小為n
step[n-1] = elemSize(每個矩陣元素的數據大小)
step[n-2] = size(1維)*elemSize
step[n-3] = size(2維)*size(1維)*elemSize
...
step[0] = size(n-1維)*size(n-2維)*...size(1維)*elemSize
8、step1
step1也是一個數組,為step/elemSize1,若矩陣有n維,則step1[n-1] = channels。
9、type
矩陣元素的類型,即創建Mat時傳遞的類型,例如CV_8UC3、CV_16UC2等。
