二维图像中Mat::setp、Mat::step1理解
? ? ? ?Mat中的step為構成圖像的層次,考慮到Mat多應用于二維圖像,本文討論二維圖像step的含義和應用。二維圖像數據存儲示意圖如下:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ?如上圖所示,該二維圖像大小為5*6,圖中元素I位于第2行第4列,該元素可具有多個通道,可為1、2、3、4;常見通道數為1或3,相應為灰度圖像或RGB圖像,RGB圖像的通道排列為B分量、G分量、R分量。
二、Mat::setp、Mat::step1
? ? ? ?對于二維圖像, setp、step1均為2維,意義為:
setp[0]: 線的數據量大小,單位為字節
setp[1]: 點的數據量大小,單位為字節
step1(0): 線的通道數量
step1(1): 點的通道數量
? ? ? ?上述線、點為構成二維圖像數據的層次,例如第2行第4列元素,線、點序號為1、3。
三、示例
? ? ? ?以下對分別對8UC3類型、16UC3類型二維數據進行測試說明
//main.cpp #include <iostream>#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp>using namespace cv; using namespace std; int M = 5; int N = 6;int main() {int n = M*N*3;uchar * data8UC3 = new uchar[n];short * data16UC3 = new short[n];for (int i = 0; i < n; ++i){data8UC3[i] = i;data16UC3[i] = i;}Mat mat8UC3(M, N, CV_8UC3, data8UC3);Mat mat16UC3(M, N, CV_16UC3, data16UC3);cout << "*************************8UC3類型二維數據**************************\n";cout << "step[0]:" << mat8UC3.step[0] //18,線大小,單位字節,8UC3,則每個通道數據只需1字節<< "\nstep[1]:" << mat8UC3.step[1] //3,點大小,單位字節<< "\nstep1(0):" << mat8UC3.step1(0) //18, 線的通道數<< "\nstep1(1):" << mat8UC3.step1(1); // 3,點的通道數cout << "\n\ncout直接輸出矩陣:\n" << mat8UC3<< "\n";cout << "\nm.addr(i,j) = m.data + step[0]*i + step[1]*j方式輸出矩陣:\n";uchar *p8UC3 = mat8UC3.data;for (int i = 0; i < M; ++i){for (int j = 0; j < N; ++j){std:cout << (int)*(p8UC3 + mat8UC3.step[0] * i + mat8UC3.step[1] * j + 0) << " "<< (int)*(p8UC3 + mat8UC3.step[0] * i + mat8UC3.step[1] * j + 1) << " "<< (int)*(p8UC3 + mat8UC3.step[0] * i + mat8UC3.step[1] * j + 2) << " ";}std::cout << "\n";}cout << "\n*************************16UC3類型二維數據**************************\n";cout << "step[0]:" << mat16UC3.step[0] //36,線大小,單位字節,16UC3,則每個通道數據只需2字節<< "\nstep[1]:" << mat16UC3.step[1] //6,點大小,單位字節<< "\nstep1(0):" << mat16UC3.step1(0) //18, 線的通道數<< "\nstep1(1):" << mat16UC3.step1(1); // 3,點的通道數cout << "\n\ncout直接輸出矩陣:\n" << mat16UC3 << "\n";cout << "\nm.addr(i,j) = m.data + step1(0)*i + step1(1)*j方式輸出矩陣:\n";short *p16UC3 = (short*)mat16UC3.data;for (int i = 0; i < M; ++i){for (int j = 0; j < N; ++j){cout << (int)*(p16UC3 + mat16UC3.step1(0) * i + mat16UC3.step1(1) * j + 0) << " "<< (int)*(p16UC3 + mat16UC3.step1(0) * i + mat16UC3.step1(1) * j + 1) << " "<< (int)*(p16UC3 + mat16UC3.step1(0) * i + mat16UC3.step1(1) * j + 2) << " ";}std::cout << "\n";}delete data8UC3;delete data16UC3;return 0; } 四、程序運行結果
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ?可見單個通道的數據量不為1字節時,由Mat::data指針訪問數據,必須使用step1(0)、step1(1),更細致了解訪問Mat中的每個像素值可看這篇博文http://blog.csdn.net/xiaowei_cqu/article/details/19839019
總結
以上是生活随笔為你收集整理的二维图像中Mat::setp、Mat::step1理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小程序开发-Step1
- 下一篇: 高中英语语法(003)-句子的要素及种类