【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等屬性的理解