OpenCV基礎篇之Mat資料結構,opencv基礎篇mat

來源:互聯網
上載者:User

OpenCV基礎篇之Mat資料結構,opencv基礎篇mat
程式及分析

/* * FileName : MatObj.cpp * Author   : xiahouzuoxin @163.com * Version  : v1.0 * Date     : Thu 15 May 2014 09:12:45 PM CST * Brief    :  *  * Copyright (C) MICL,USTB */#include <cv.h>#include <highgui.h>#include <iostream>using namespace std;using namespace cv;int main(void){    /*     * Create Mat     */    Mat M(2,2,CV_8UC3, Scalar(0,0,255));    cout << "M=" << endl << " " << M << endl << endl;    /*     * Matlab style     */    Mat E = Mat::eye(4,4,CV_64F);    cout << "E=" << endl << " " << E << endl << endl;    E = Mat::ones(4,4,CV_64F);    cout << "E=" << endl << " " << E << endl << endl;    E = Mat::zeros(4,4,CV_64F);    cout << "E=" << endl << " " << E << endl << endl;    /*     * Convert IplImage to Mat     */    IplImage *img = cvLoadImage("../test_imgs/Lena.jpg");    Mat L(img);    namedWindow("Lena.jpg", CV_WINDOW_AUTOSIZE);     imshow("Lena.jpg", L);    waitKey(0);    /*     * Init Mat with separated data     */    Mat C = (Mat_<int>(3,3) << 0,1,2,3,4,5,6,7,8);    cout << "C=" << endl << " " << C << endl << endl;    return 0;}
  1. Mat是OpenCV最基本的資料結構,Mat即矩陣(Matrix)的縮寫,Mat資料結構主要包含2部分:Header和Pointer。Header中主要包含矩陣的大小,儲存方式,儲存地址等資訊;Pointer中儲存指向像素值的指標。我們在讀取圖片的時候就是將圖片定義為Mat類型,其重載的建構函式一大堆,

    class CV_EXPORTS Mat{public:    //! default constructor    Mat();    //! constructs 2D matrix of the specified size and type    // (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)    Mat(int _rows, int _cols, int _type);    Mat(Size _size, int _type);    //! constucts 2D matrix and fills it with the specified value _s.    Mat(int _rows, int _cols, int _type, const Scalar& _s);    Mat(Size _size, int _type, const Scalar& _s);    //! constructs n-dimensional matrix    Mat(int _ndims, const int* _sizes, int _type);    Mat(int _ndims, const int* _sizes, int _type, const Scalar& _s);    //! copy constructor    Mat(const Mat& m);    //! constructor for matrix headers pointing to user-allocated data    Mat(int _rows, int _cols, int _type, void* _data, size_t _step=AUTO_STEP);    Mat(Size _size, int _type, void* _data, size_t _step=AUTO_STEP);    Mat(int _ndims, const int* _sizes, int _type, void* _data, const size_t* _steps=0);    //! creates a matrix header for a part of the bigger matrix    Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all());    Mat(const Mat& m, const Rect& roi);    Mat(const Mat& m, const Range* ranges);    //! converts old-style CvMat to the new matrix; the data is not copied by default    Mat(const CvMat* m, bool copyData=false);    //! converts old-style CvMatND to the new matrix; the data is not copied by default    Mat(const CvMatND* m, bool copyData=false);    //! converts old-style IplImage to the new matrix; the data is not copied by default    Mat(const IplImage* img, bool copyData=false);    ......    }

    要瞭解如何初始化Mat結構,就應該瞭解它的建構函式,比如程式中的第一初始化方式調用額就是

    Mat(int _rows, int _cols, int _type, const Scalar& _s);

    這個建構函式。

    IplImage*是C語言操作OpenCV的資料結構,在當時C操縱OpenCV的時候,地位等同於Mat,OpenCV為其提供了一個介面,很方便的直接將IplImage轉化為Mat,即使用建構函式

    Mat(const IplImage* img, bool copyData=false);

    上面程式中的第二種方法就是使用的這個建構函式。

  2. 關於Mat資料複製:前面說過Mat包括頭和資料指標,當使用Mat的建構函式初始化的時候,會將頭和資料指標複製(注意:只是指標複製,指標指向的地址不會複製),若要將資料也複製,則必須使用copyTo或clone函數

  3. Mat還有幾個常用的成員函數,在之後的文章中將會使用到:

    //! returns true iff the matrix data is continuous// (i.e. when there are no gaps between successive rows).// similar to CV_IS_MAT_CONT(cvmat->type)bool isContinuous() const;

    這瞭解上面的函數作用前,得瞭解下OpenCV中儲存像素的方法,如下,灰階圖(單通道)儲存按行列儲存,

    三通道RGB儲存方式如下,每列含有三個通道,

    為了加快訪問的速度,openCV往往會在記憶體中將像素資料連續地儲存成一行,isContinus()函數的作用就是用於判斷是否連續儲存成一行。儲存成一行有什麼好處呢?給定這行的頭指標p,則只要使用p++操作就能逐個訪問資料。

    因此當判斷存放在一行的時候,可以通過資料指標++很容易遍曆映像像素:

    long nRows = M.rows * M.channels();  // channels()也是Mat中一個常用的函數,用於擷取通道數(RGB=3,灰階=1)long nCols = M.cols;uchar *p = M.data;  // 資料指標if(M.isContinuous()){    nCols *= nRows;    for (long i=0; i < nCols; i++) {        *p++ = ...; // 像素賦值或讀取操作    }       }

    請注意以上幾個常用的Mat成員遍曆和函數:

    M.row; // 返回映像行數M.nCols;  // 返回映像列數M.channels();  //返回通道數M.isContinuous(); // 返回bool類型表示是否連續儲存
相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.