【3】OpenCV入門-Mat詳解

聲明:本博客部分參考《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++;
    }
}

 

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