®.運行環境:Linux(RedHat+OpenCV3.0)ios
Mat類用於表示一個多維的單通道或者多通道的稠密數組。可以用來保存實數或複數的向量、矩陣,灰度或彩色圖像,立體元素,點雲,張量以及直方圖(高維的直方圖使用SparseMat保存比較好)。簡而言之,Mat就是用來保存多維的矩陣的。c++
uchar類型的指針,指向Mat數據矩陣的首地址。能夠理解爲標示一個房屋的門牌號;數組
Mat矩陣的維度,若Mat是一個二維矩陣,則dims=2,三維則dims=3,大多數狀況下處理的都是二維矩陣,是一 個平面上的矩陣。安全
能夠理解爲房屋是一個一層的平房,三維或更多維的則是多層樓房;數據結構
Mat矩陣的行數。可理解爲房屋內房間行數;函數
Mat矩陣的列數。可理解爲房屋內房間列數;佈局
首先size是一個結構體,定義了Mat矩陣內數據的分佈形式,數值上有關係式:spa
image.size().width==image.cols; image.size().height==image.rows .net
能夠理解爲房屋內房間的總體佈局,這其中包括了房間分別在行列上分佈的數量信息;指針
Mat矩陣元素擁有的通道數。例如常見的RGB彩色圖像,channels==3;而灰度圖像只有一個灰度份量信息, channels==1。
能夠理解爲每一個房間內放有多少牀位,3通道的放了3張牀,單通道的放了1張牀;
用來度量每個像素中每個通道的精度,但它自己與圖像的通道數無關!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}
其中U是unsigned的意思,S表示signed,也就是有符號和無符號數。
能夠理解爲房間內每張牀能夠睡多少人,這個跟房間內有多少牀並沒有關係;
elem是element(元素)的縮寫,表示矩陣中每個元素的數據大小,若是Mat中的數據類型是CV_8UC1,那麼 elemSize==1;若是是CV_8UC3或CV_8SC3,那麼elemSize==3;若是是CV_16UC3或者CV_16SC3,那麼 elemSize==6;即elemSize是以8位(一個字節)爲一個單位,乘以通道數和8位的整數倍;
能夠理解爲整個房間能夠睡多少人,這個時候就得累計上房間內全部牀位數(通道)和每張牀的容納量了;
elemSize加上一個「1」構成了elemSize1這個屬性,1能夠認爲是元素內1個通道的意思,這樣從命名上拆分後就很 容易解釋這個屬性了:表示Mat矩陣中每個元素單個通道的數據大小,以字節爲一個單位,因此有:
eleSize1==elemSize/channels;
能夠理解爲Mat矩陣中每一行的「步長」,以字節爲基本單位,每一行中全部元素的字節總量,是累計了一行中所 有元素、全部通道、全部通道的elemSize1以後的值;
以字節爲基本單位,Mat矩陣中每個像素的大小,累計了全部通道、全部通道的elemSize1以後的值,因此有:
step1==step/elemSize1;
Mat矩陣的類型,包含有矩陣中元素的類型以及通道數信息,type的命名格式爲CV_(位數)+(數據類型)+(通道數),全部取值以下:
注:一、在程序的最開始加上: using namespace cv; 二、把Mat改成 cv::Mat (因爲本人不會C++全部開始有點沒明白如何使用函數)
建立Mat類的方式:1.構造函數 2.create()函數建立對象3.從已有的數據源初始化
1.構造函數
Mat::Mat()
無參數構造方法;
Mat::Mat(int rows, int cols, int type)
建立行數爲 rows,列數爲col,類型爲type的圖像;
Mat::Mat(Size size, int type)
建立大小爲 size,類型爲type的圖像;
Mat::Mat(int rows, int cols, int type, const Scalar& s)
建立行數爲rows,列數爲col,類型爲type的圖像,並將全部元素初始化爲值s;
Mat::Mat(Size size, int type, const Scalar& s)
建立大小爲 size,類型爲type的圖像,並將全部元素初始化爲值s
Mat::Mat(const Mat& m)
將 m 賦值給新建立的對象,此處不會對圖像數據進行復制, m 和新對象共用圖像數據;
Mat::Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP)
建立行數爲 rows,列數爲col,類型爲type的圖像,此構造函數不建立圖像數據所需內存,而是直接使用data所指內存,圖像的行步長由step指定。
Mat::Mat(Size size, int type, void* data, size_t step=AUTO_STEP)
建立大小爲 size,類型爲type的圖像,此構造函數不建立圖像數據所需內存,而是直接使用data所指內存,圖像的行步長由step指定。
Mat::Mat(const Mat& m, const Range& rowRange, const Range& colRange)
建立的新圖像爲 m 的一部分,具體的範圍由 rowRange 和 colRange 指定,此構造函數也不進行圖像數據的複製操做,新圖像與m共用圖像數據;
Mat::Mat(const Mat& m, const Rect& roi)
建立的新圖像爲 m 的一部分,具體的範圍 roi 指定,此構造函數也不進行圖像數據的複製操做,新圖像與m共用圖像數據。
type的類型有CV_8UC1,CV_16SC1,…,CV_64FC4等。裏面的8U表示8位無符號整數,16S表示16位有符號整數,64F表示64位浮點數(即double類型);C後面的數表示通道數,例如C1表示一個通道的圖像,C4表示4個通道的圖像,以此類推。
若是你須要更多的通道數,須要用宏CV_8UC(n),例如:Mat M(3,2, CV_8UC(5));//建立行數爲3,列數爲2,通道數爲5的圖像
計算機視覺中,圖像的讀取是圖像處理的基礎,圖像就是一系列像素值,OpenCV使用數據結構cv::Mat來存儲圖像。cv::Mat是一個矩陣類,矩陣中每個元素都表明一個像素,對於灰度圖像,像素用8位無符號數,0表示黑色,255表示白色。對於彩色像素而言,每一個像素須要三位這樣的8位無符號數來表示,即三個通道(R,G,B),矩陣則依次存儲一個像素的三個通道的值,而後再存儲下一個像素點。
cv::Mat中,
cols表明圖像的寬度(圖像的列數),
rows表明圖像的高度(圖像的行數),
step表明以字節爲單位的圖像的有效寬度,
elemSize返回像素的大小,
channels()方法返回圖像的通道數,
total函數返回圖像的像素數。
像素的大小 = 顏色大小(字節)*通道數,
好比:
三通道short型矩陣(CV_16SC3)的大小爲2*3 = 6,
三通道Byte型矩陣(CV_8UC3)的大小爲1*3= 3,像素的channels方法返回圖像的通道數,total函數返回圖像的像素數。
RGB圖像的顏色數目是256*256*256,本文對圖像進行量化,縮減顏色數目到256的1/8(即32*32*32)爲目標,分別利用一下幾種方法實現,比較幾種方法的安全和效率。
方法一:使用Mat的成員函數ptr<>()
cv::Mat中提供ptr函數訪問任意一行像素的首地址,特別方便圖像的一行一行的橫向訪問,若是須要一列一列的縱向訪問圖像,就稍微麻煩一點。可是ptr訪問效率比較高,程序也比較安全,有越界判斷。
方法二:使用迭代器遍歷圖像
cv::Mat一樣有標準模板庫(STL),可使用迭代器訪問數據。
用迭代器來遍歷圖像像素,可簡化過程下降出錯的機會,比較安全,不過效率較低;若是想避免修改輸入圖像實例cv::Mat,可採用const_iterator。iterator有兩種調用方法,cv::MatIterator_<cv::Vec3b>it;cv::Mat_<cv::Vec3b>::iterator it;中間cv::Vec3b是由於圖像是彩色圖像,3通道,cv::Vec3b能夠表明一個像素。
方法三:使用Mat的成員函數at<>()
cv::Mat也是向量,可使at方法取值,使用調用方法image.at<cv::Vec3b>(j,i),at方法方便,直接給i,j賦值就能夠隨意訪問圖像中任何一個像素,其中j表示第j行,i表示該行第i個像素。可是at方法效率是這3中訪問方法中最慢的一個,因此若是遍歷圖像或者訪問像素比較多時,建議不要使用這個方法,畢竟程序的效率仍是比程序的可讀性要重要的。下面是完整的調用方法,其運行時間在下面會介紹。
注意:使用at函數時,應該知道矩陣元素的類型和通道數,根據矩陣元素類型和通道數來肯定at函數傳遞的類型,使用的是Vec3b這個元素類型,他是一個包含3個unsigned char類型向量。之因此採用這個類型來接受at的返回值,是由於,咱們的矩陣im是3通道,類型爲unsigned char類型
完整實例:
時間:2018.1.21.1.41{失眠夜總結OpenCV吧想起了一段話送給本身}{Can not force others to love themselves only to make themselves worthy of love ,and the rely on fate.}@晚安 Liu在身邊 27