1. 程式人生 > >把OpenCV Mat當一個普通陣列來用

把OpenCV Mat當一個普通陣列來用

  最近在移植MATLAB影象處理演算法,要將這個演算法移植到OpenCV當中去,因為MATLAB對於陣列的操作非常簡單,而C++裡面的陣列就沒那麼好用,於是就想到了要用OpenCVMat
  在網上,關於OpenCV,關於Mat的文章,程式碼都非常多,但是都是相對簡單的應用,當做一個影象資料來用,用到的格式也基本都是CV_8UCV_8UC3型別。
  CV_8UC就是建立單通道的影象,在讀取影象的時候就用image.at<uchar>(i,j)來進行畫素值讀取。CV_8UC3就是建立三通道影象,讀取影象的時候就用image.at<Vec3b>(i,j)[k]

來進行讀取。除了這兩種形式,基本上就有了。但確實,Mat型別還有很多型別和應用
  首先來講一下如何建立一個三維的矩陣,如果此刻我要建立一個6×6×6的矩陣,那就應該Mat MatArray(6,6,CV_8UC(6),稍微解釋一下這個型別,88 bits的意思,就是char型,然後這裡的Uunsigned的意思,看這個型別的樣子跟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之類的型別。相關的定義在OpenCVtypes_c.hcore.hpp中都有。

Mat MatArray30x30; 
MatArray30x30.create(30,30,CV_32SC(81));

  上面是建立一個30×3081維向量。