【opencv】cv::Mat 公有屬性 (Public Attributes)

  • 2020 年 3 月 12 日
  • 筆記

作用

影像在OpenCV中都是通過Mat類來存儲的,Mat可以用來表示N維矩陣。

Public Attributes

主要包含兩部分:

  • 用來描述矩陣的頭資訊;
  • data指針,指向Mat中存儲的數據。

type

attr

備註

MatAllocator *

allocator

const uchar *

dataend

const uchar *

datalimit

const uchar *

datastart

int

flags

int

dims

維數

int

rows

行數

int

cols

列數

MatSize

size

結構體,表示每一行佔據的位元組數目(包括padding數);image.size().width = image.cols;image.size().height = image.rows

MatStep

step

UMatData *

u

uchar *

data

uchar類型的指針,指向Mat數據矩陣的首地址

Note:

  • 如果data中沒有padding,我們可以把矩陣的data當一維數據處理,數據長度就是rowscolselemSize()。

Code Example

新建Mat

創建一個5×5×3的3維矩陣,數據類型為8bit無符號數,初始值都為(0,0,255)

cv::Mat M(5,5, CV_8UC3, cv::Scalar(0,0,255));

其對應的可視化矩陣如下:

拷貝Mat

這裡以 「從M拷貝出N」 為例。

1. 淺拷貝

只是新生成一個矩陣頭,它的data指針依然指向M.data。

Mat N(M);

or

Mat N = M;

2. 深拷貝

生成一個全新的矩陣:不但拷貝矩陣的頭資訊,而且會生成一個data的拷貝(即data指針指向不同的地址)。

Mat N = M.clone();

or

Mat N;  M.copyTo(N);

其中,copyTo函數還可以帶有掩碼矩陣copyTo(G, maskImage)。 maskImage是一個單通道的矩陣,值為0的位置,在拷貝時候並不會被拷貝到:

訪問data中元素

這裡以二維矩陣為例,若是多維矩陣,則相應增加for循環。

1. 直接訪問

for(i=0; i< M.rows; i++)  {      for(j=0; j<M.cols*M.elemSize(); j++)     {         printf ("%d ", M.data[i*M.cols*M.elemSize() + j]);     }     printf("n");  }

2. 指針訪問

uchar* p;  for( i = 0; i < M.rows; ++i)  {      // 得到第i行的指針,等價於 p = M.data + i*M.step      p = M.ptr<uchar>(i);      for ( j = 0; j < M.cols; ++j)      {        printf (" %d %d %d",p[j*3], p[j*3+1],p[j*3+2]);       }      printf("n");  }

3. at訪問

也可以用at的方式得到數組元素。 M.atcv::Vec3b(i,j)[2]得到元素中的第2個分量; 如果M.at(i,j),則只能取到元素的第一個分量。

for(i=0; i< M.rows; i++)      {      for(j=0; j<M.cols; j++)          {          printf ("%d %d %d ", M.at<cv::Vec3b>(i,j)[0],M.at<cv::Vec3b>(i,j)[1], M.at<cv::Vec3b>(i,j)[2]);          }      printf("n");      }  }

4. 迭代器訪問

cv::MatIterator_<cv::Vec3b> it, end;  for( it = M.begin<cv::Vec3b>(), end = M.end<cv::Vec3b>(); it != end; ++it)  {      printf("%d %d %dn",(*it)[0], (*it)[1], (*it)[2]);  }

取區域塊

取出矩陣的某個ROI區域,以便進行處理。

cv::Rect rect(50, 50, 100, 100);   // 要切取的區域(x1, y1, x2, y2)  srcImage(rect).copyTo(roiImage); 

線性變換

生成一個新矩陣,矩陣的中值為原矩陣中的值乘以alpha,然後再加上beta。

convertTo(OutputArray m, int rtype, double alpha=1, double beta=0 )

例如,實現 M(x,y) = N(x,y) × 10 + 255 :

N.convertTo(M, CV_8U, 10, 255);

參考文獻

[1] cv::Mat Class Reference [2] OpenCV學習(4) Mat的基本操作(1) [3] OpenCV學習(5) Mat的基本操作(2) [4] OpenCV—矩陣數據類型轉換cv::convertTo [5] Opencv Mat矩陣中data、size、depth、elemSize、step等屬性的理解