zoukankan      html  css  js  c++  java
  • OpenCV基础篇之Mat数据结构

    OpenCV基础篇之Mat数据结构

    http://www.2cto.com/database/201408/329749.html



    程序及分析

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    /*
     * 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;
     
    intmain(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;
     
     
        return0;
    }

    Mat是OpenCV最基本的数据结构,Mat即矩阵(Matrix)的缩写,Mat数据结构主要包含2部分:Header和Pointer。Header中主要包含矩阵的大小,存储方式,存储地址等信息;Pointer中存储指向像素值的指针。我们在读取图片的时候就是将图片定义为Mat类型,其重载的构造函数一大堆,

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    class CV_EXPORTS Mat
    {
    public:
        //!defaultconstructor
        Mat();
        //! constructs 2D matrix ofthe specified sizeand type
        // (_type isCV_8UC1, CV_64FC3, CV_32SC(12) etc.)
        Mat(int_rows, int_cols, int_type);
        Mat(Size_size, int_type);
        //! constucts 2D matrix andfills it withthe 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 formatrix headers pointing touser-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 fora part ofthe 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 tothe new matrix; the data isnot copied bydefault
        Mat(const CvMat* m, bool copyData=false);
        //! converts old-style CvMatND tothe new matrix; the data isnot copied bydefault
        Mat(const CvMatND* m, bool copyData=false);
        //! converts old-style IplImage tothe new matrix; the data isnot copied bydefault
        Mat(const IplImage* img, bool copyData=false);
     
        ......
        }

    要了解如何初始化Mat结构,就应该了解它的构造函数,比如程序中的第一初始化方式调用额就是

    ?
    1
    Mat(int_rows, int_cols, int_type, const Scalar& _s);

    这个构造函数。

    IplImage*是C语言操作OpenCV的数据结构,在当时C操纵OpenCV的时候,地位等同于Mat,OpenCV为其提供了一个接口,很方便的直接将IplImage转化为Mat,即使用构造函数

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

    上面程序中的第二种方法就是使用的这个构造函数。

    关于Mat数据复制:前面说过Mat包括头和数据指针,当使用Mat的构造函数初始化的时候,会将头和数据指针复制(注意:只是指针复制,指针指向的地址不会复制),若要将数据也复制,则必须使用copyTo或clone函数

    mat

    Mat还有几个常用的成员函数,在之后的文章中将会使用到:

    ?
    1
    2
    3
    4
    //!returnstrue iff the matrix data iscontinuous
    // (i.e. whenthere are nogaps betweensuccessive rows).
    // similar toCV_IS_MAT_CONT(cvmat->type)
    bool isContinuous() const;

    这了解上面的函数作用前,得了解下OpenCV中存储像素的方法,如下,灰度图(单通道)存储按行列存储,

    single_channel

    三通道RGB存储方式如下,每列含有三个通道,

    rgb_channel

    为了加快访问的速度,openCV往往会在内存中将像素数据连续地存储成一行,isContinus()函数的作用就是用于判断是否连续存储成一行。存储成一行有什么好处呢?给定这行的头指针p,则只要使用p++操作就能逐个访问数据。

    因此当判断存放在一行的时候,可以通过数据指针++很容易遍历图像像素:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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成员遍历和函数:

    ?
    1
    2
    3
    4
    M.row; // 返回图像行数
    M.nCols;  // 返回图像列数
    M.channels();  //返回通道数
    M.isContinuous(); // 返回bool类型表示是否连续存储

    更多关于Mat的信息请参考安装目录下的include/opencv2/core.hpp文件

    效果

    result

    左边是矩阵的一些操作输出结果,右边的图是通过IplImage *结构读入,转换为Mat后显示结果

  • 相关阅读:
    asp.net 中@Html.Partial,@Html.Action,@Html.RenderPartial,@Html.RenderAction
    mvc EF 执行SQL语句
    MVC 自定义AuthorizeAttribute实现权限管理
    EF
    sql 、linq、lambda 查询语句的区别
    说说C#中的enum吧
    C# A窗口内容显示在B窗口中的方法
    C# 程序开始主要是写类和方法 的基本步骤和调用方法
    C# 文件流基本操作步骤
    Ghost命令使用方法
  • 原文地址:https://www.cnblogs.com/fag888/p/5789172.html
Copyright © 2011-2022 走看看