OpenCV中Mat的建立,高維度Mat的建立,以及各維度下值的索引問題,詳細解析!

你看完這篇文章之後,將學會以下知識:

  • ① 二維、三維、四維等任意維度的Mat的常用建立方法;
  • ② 任意維度Mat中值的索引;
  • ③ 以及一些Mat常用的操作。

下面是對各維度矩陣的介紹:

  注意:下面的操作只是我常用的操作方法,不是唯一的方法,對於那些沒有思路的同學,下面的內容希望起到拋磚引玉的效果。

  我以單通道的uchar類型的圖片做例子

1. 二維Mat

  二維的Mat是我們最常使用的類型,它就和我們的圖片直接對應

構造函數:Mat(int rows, int cols, int type, const Scalar& s);
變量聲明:cv::Mat mat2D(100, 100, CV_8UC1, cv::Scalar(0));

  上述變量聲明的代碼,定義了一個100x100的Mat,它有一個通道,通道中的數據類型都是uchar,每一個對應位置的值都是0。

對於這種二維矩陣的索引,有多種方法:
  第一種(效率不高)

uchar a = mat2D.at<uchar>(i,j)

  第二種

uchar* a = mat2D.ptr<uchar>(0);//指針指向mat2D的0行首地址
uchar a = mat2D.ptr<uchar>(1)[5];//取出(1,5)中的值

2. 三維Mat

  三維Mat一般很少用,對於它的操作:

構造函數:Mat(int ndims, const int* sizes, int type);

變量聲明:
int size[3] = {100, 100, 100};
cv::Mat mat3D(3, size, CV_8UC1, cv::Scalar(0));

  上面變量聲明的代碼,聲明瞭一個維度爲3,大小爲100x100x100的Mat。

對於三維Mat的索引:
  第一種方法(效率不高)

uchar a = mat3D.at<uchar>(4,5,6);//取出(4,5,6)中對應的值

  第二種方法

uchar* a = mat3D.ptr<uchar>(0,0);//a指向前兩維限定下的行首的地址
uchar a = mat3D.ptr<uchar>(0,0)[4];//取出(0,0,4)中的值

3. 四維Mat

int size[4] = {100, 100, 100, 100};
cv::Mat mat4D(4, size, CV_8UC1, cv::Scalar(0));

對於四維Mat的索引,不能使用at函數,因爲不支持超過三維的Mat

uchar* a = mat3D.ptr<uchar>(0,0,0)[4];//取出(0,0,0,4)中對應的值

4. 五維Mat

int size[5] = {100, 100, 100, 100100};
cv::Mat mat5D(5, size, CV_8UC1, cv::Scalar(0));

  大於四維的Mat,既不能使用at,也不能使用ptr訪問元素。下面介紹我常用的方法:這裏我們可以使用Mat類中的data成員變量,它指向Mat數據區的首地址,對於Mat類型的數據,它們是按照線性方式存值的,我們知道首地址之後,就可以通過指針偏移的方式,去索引任意元素的值。
對於 100x100x100x100x100 的五維Mat,如果索引要 [a,b,c,d,e] 中的值,則可以使用下面的方式

uchar a = *(mat5D.data + a*100*100*100*100 + b*100*100*100 + c*100*100 + d*100 + e);

  如果你在Mat中存儲的不是CV_8UC1,而是別的類型,比如是CV_32FC1,那麼就不能直接使用data,因爲它默認是uchar類型的指針,需要將它強轉爲float類型。代碼如下:

float a = *((float*)mat5D.data + a*100*100*100*100 + b*100*100*100 + c*100*100 + d*100 + e);

對於更高維的情況,使用上面的五維的方法推廣就行,當然上述所有的方法,都不是最好的或者是唯一的,只是我個人比較常用的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章