聲明:本博客部分參考《OpenCV3編程入門》這本書
1.Mat與lpIlmage對象
Mat對象是OpenCV2.0之後引進的圖像數據結構、自動分配內存、不存在內存泄漏問題,是面向對象
的數據結構。Mat分頭部和數據部分。
lpllmage是從2001年OpenCV發佈之後就一直存在的,是C語言風格的數據結構,需要開發者自己分配
和管理內存,容易造成內存泄漏。
2.Mat中的常見函數
(1)構造函數
(2)其他方法
void copyTo(Mat mat)
void convertTo(Mat dst, int type)
Mat clone()
int channels()
int depth()
bool empty();
uchar* ptr(i=0)
3.Mat創建
(1)通過構造函數
Mat c(300, 300, CV_8UC3, Scalar(255,0,0));
上面的代碼會生成一個藍色的300x300的窗口。
①前兩個參數分別爲圖像的高(row)和寬(col)
②CV_8UC3表示圖像的格式:CV_[位數][帶符號與否][類型前綴]C[通道數]:數據類型和通道數。其中通道數也可以不指定
常見的有:CV_8UC1、CV_8UC3、CV_8UC4、CV_32FC1、CV_32FC3、CV_32FC4
③最後一位是顏色值:OpenCV中三原色的分佈是按Blue、Green、Red來的。
備註:這種方式創建的是二維矩陣,下面介紹創建維數大於等於3的矩陣。
int sz[3] = {2,2,2};
Mat L(3,sz,CV_8UC,Scalar::all(0));
①參數一指定維數,上述代碼中爲3。
②參數二指定各個維數的大小。
③參數三、四見前面介紹。其中all(0)表示BGR分量都是0。
(2)通過create函數構造
Mat c;
c.create(300, 300, CV_8UC3);
這種方式有個缺陷,你不可以給你創建的圖像直接設置顏色。
(3)採用Matlab中的方法
//4x4的單位矩陣
Mat E = Mat::eye(4,4,CV_64F)
//2x2的1矩陣
Mat O = Mat::ones(2,2,CV_32F);
//3x3的0矩陣
Mat Z = Mat::zeros(3,3,CV_8UC1);
(4)使用逗號分隔符初始化
Mat C = (Mat_<double>(3,3) << 0,-1,0,-1,5,-1,0,-1,0)
//生成3x3的矩陣
4.Mat的拷貝
普通的賦值和拷貝只會拷貝Mat結構的頭部,只有clone()和copyTo()才能實現完全拷貝
Mat F = A.clone();
A.copyTo(G);
A.copyTo(G,CV_8UC3);
其中copyTo()可以指定拷貝往的Mat對象的數據類型。
5.Mat對象元素的輸出顯示
(1)直接使用“<<”運算符
Mat c(2, 2, CV_8UC3, Scalar(255, 255, 255));
cout << c;
//[255, 255, 255, 255, 255, 255;
//255, 255, 255, 255, 255, 255]
這裏就要將以下Mat中的數據組織形式了,上面代碼中c是三通道的,所以每個像素有3個顏色值,所有每一行3個值表示一個像素。
(2)使用"<<"+format()函數
Mat r(2, 2, CV_8UC3, Scalar(255, 255, 255));
//python風格輸出
cout << "Python" << endl;
cout << format(r, Formatter::FMT_PYTHON) << endl;
//逗號風格輸出
cout << "逗號" << endl;
cout << format(r, Formatter::FMT_CSV) << endl;
//Numpy風格輸出
cout << "Numpy" << endl;
cout << format(r, Formatter::FMT_NUMPY) << endl;
//c風格輸出
cout << "C語言" << endl;
cout << format(r, Formatter::FMT_C) << endl;
/*Python
[[[255, 255, 255], [255, 255, 255]],
[[255, 255, 255], [255, 255, 255]]]
逗號
255, 255, 255, 255, 255, 255
255, 255, 255, 255, 255, 255
Numpy
array([[[255, 255, 255], [255, 255, 255]],
[[255, 255, 255], [255, 255, 255]]], dtype='uint8')
C語言
{255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255}*/
6.Mat對象的一些屬性
(1)Mat::rows和Mat::cols,這兩個分別是圖像的行數(高)和列數(寬),都是公有變量可以直接訪問
(2)Mat::channels()-返回圖像的通道數。
(3)Mat::depth()-返回圖像的深度,即Mat中的數據類型8U或者32F,不考慮通道數。
(4)Mat::type()-圖像的數據類型。
7.訪問圖像中的單個像素
(1)at()方法
//訪問單通道圖像
uchar pixle = src.at<uchar>(row,col);
//訪問多通道圖像(CV_8UC3)
Vec3b bgr = src.at<Vec3b>(row,col);
//(CV_32UC3)
Vec3f bgr = src.at<Vec3f>(row,col);
需要結合圖像的type()類型來操作。
(2)指針操作
for (size_t row = 0; row < rows; ++row)
{
//獲取行指針
uchar *prow = cornerImage.ptr(row);
for (size_t col = 0; col < cols; ++col)
{
int rvalue = static_cast<int>(*prow);
prow++;
}
}