OpenCV Mat类

Mat类有两个部分:矩阵头和指向矩阵数据部分的指针

矩阵头中包含矩阵的尺寸、存储方法、地址和引用次数等,矩阵头的大小是一个常数。

由于矩阵数据较大,传递时只是传递矩阵头和数据指针,即共同指向同一块数据内存。除非深拷贝或移动,即clone或std::move。

    cv::Mat src1 = cv::imread("d:/1.jpg");  //cv::imread会开辟内存Memory1,src1中的数据指针指向Memory1
    cv::Mat src2 = src1;                    //src2中的数据指针指向Memory1
    src1 = cv::imread("d:/2.jpg");          //开辟内存Memory2,src1中的数据指针指向Memory2。src2中的数据指针依然指向Memory1
    cv::imshow("src1", src1);               //2.jpg
    cv::imshow("src2", src2);               //1.jpg

    //cv::Mat src3 = src1;                  //浅拷贝,指向同一内存
    //cv::Mat src3 = src1.clone();          //clone会开辟内存
    cv::Mat src3 = std::move(src1);         //比clone效率高,内存所有权被转移而不是新开辟。即src3中的数据指针指向该内存,src1中的数据指针悬空
                                            //因此,std::move使用要注意:src1的内存数据一定不会被再次使用(指针悬空,无法再操作原有数据了)。
    src1=cv::imread("d:/3.jpg");            //src1中的数据指针不再悬空,指向新内存
    
    cv::waitKey(0);

如果不理解,可以参考下述案例

    int a = 10;          //开辟内存Memory1
    int *pA1 = &a;
    int *pA2 = pA1;      //pA1、pA2都指向Memory1
    std::cout << a << " " << *pA1 << " " << *pA2 << std::endl;    //10 10 10
    a = 11;
    std::cout << a << " " << *pA1 << " " << *pA2 << std::endl;    //11 11 11
    int b = 20;          //开辟内存Memory2
    pA1 = &b;            //pA1指向Memory2,pA2依然指向Memory1
    std::cout << a << " " << *pA1 << " " << *pA2 << std::endl;    //11 20 11

 其他参考

  c++ 为什么std::move()没有窃取一个int值? _大数据知识库 (saoniuhuo.com) 

  【OpenCV】浅谈 Mat 类_opencv mat-CSDN博客

经典场景:踩坑,C++ Opencv中Mat对象作消息队列参数时候出现队列中数据完全一样的情况_c++ mat相等-CSDN博客

    queue<Mat> videoframes;
    Mat frame;
    VideoCapture capture;

    capture.open("./data/output.mp4");
    if (!capture.isOpened())
    {
        return;
    }
    videoframes = queue<Mat>();
    while (capture.read(frame))
    {
        qDebug("add one frame");
        videoframes.push(frame);//队列中所有元素都是最后进入的那一张
        //videoframes.push(frame.clone()); //方法1
        //videoframes.push(move(frame)); //方法2
    }    

 

Mat类的属性:

  • rows  矩阵的行数
  • cols   矩阵的列数
  • dims  矩阵的维度,例如5*6矩阵是二维矩阵,则dims=2,三维矩阵dims=3.
  • data uchar类型的指针,指向Mat数据矩阵的首地址。

Mat类的方法:

  • size()   矩阵的大小,宽×高(列×行)
  • channels() 矩阵元素拥有的通道数,例如常见的彩色图像,每一个像素由RGB三部分组成,则channels = 3

【参考】

https://www.cnblogs.com/faith0217/articles/4708877.html

【案例】

    Mat kernel = (Mat_<char>(2, 3) << 0, -1, 0,-1, 5, -1); 
    cout << kernel << endl;
    cout << kernel.rows << endl;
    cout << kernel.cols << endl;
    cout << kernel.size()<<endl;
    cout << kernel.channels() << endl;
    cout << kernel.dims << endl;
    waitKey();
    return 0;

posted @ 2019-11-13 17:45  夕西行  阅读(865)  评论(0编辑  收藏  举报