把OpenCV Mat當一個普通陣列來用
最近在移植MATLAB影象處理演算法,要將這個演算法移植到OpenCV當中去,因為MATLAB對於陣列的操作非常簡單,而C++裡面的陣列就沒那麼好用,於是就想到了要用OpenCV的Mat。
在網上,關於OpenCV,關於Mat的文章,程式碼都非常多,但是都是相對簡單的應用,當做一個影象資料來用,用到的格式也基本都是CV_8U和CV_8UC3型別。
CV_8UC
就是建立單通道的影象,在讀取影象的時候就用image.at<uchar>(i,j)
來進行畫素值讀取。CV_8UC3
就是建立三通道影象,讀取影象的時候就用image.at<Vec3b>(i,j)[k]
首先來講一下如何建立一個三維的矩陣,如果此刻我要建立一個6Mat MatArray(6,6,CV_8UC(6)
,稍微解釋一下這個型別,8是8 bits的意思,就是char型,然後這裡的U是unsigned的意思,看這個型別的樣子跟CV_8UC3很像,那為什麼這裡要把6用括號括起來呢。我們轉到CV_8UC3的定義去看一下。
#define CV_8UC1 CV_MAKETYPE(CV_8U,1)
#define CV_8UC2 CV_MAKETYPE(CV_8U,2)
#define CV_8UC3 CV_MAKETYPE(CV_8U,3)
#define CV_8UC4 CV_MAKETYPE(CV_8U,4)
#define CV_8UC(n) CV_MAKETYPE(CV_8U,(n))
我們在types_c.h標頭檔案中看到了這個定義,從這個定義裡面我們可以看到OpenCV將常用的一些型別進行了定義,其餘的進行另一類定義。我們讀取CV_8UC3的時候是image.at<Vec3b>(i,j)[k]
這樣來進行讀取的,那CV_8UC(6)
這個是怎麼讀取的呢,那我們轉到<Vec3b>
的定義看一下。
typedef Vec<uchar, 2> Vec2b;
typedef Vec<uchar, 3> Vec3b;
typedef Vec<uchar, 4> Vec4b;
在core.hpp標頭檔案中,有以上的定義,同樣,我們平常用的<Vec3b>
是Vec<uchar,3>
的一個縮寫,那我們要訪問CV_8UC(6)
的話,就直接用Vec<uchar,6>
這樣的形式去訪問就行了,也就是image.at<Vec<uchar,6>>(i,j)[k]
。
上面講到的都是uchar型別的,只能是8 bits的無符號整形,那我要用int型,float型或者有符號型的呢,那這裡就需要用到CV_32FC
,CV_64SC
之類的型別。相關的定義在OpenCV的types_c.h和core.hpp中都有。
Mat MatArray30x30;
MatArray30x30.create(30,30,CV_32SC(81));
上面是建立一個30