Mat函数

        Mat本质上是由两个数据部分组成的类: (包含信息有矩阵的大小,用于存储的方法,矩阵存储的地址等) 的矩阵头和一个指针,指向包含了像素值的矩阵(可根据选择用于存储的方法采用任何维度存储数据)。矩阵头部的大小是恒定的。然而,矩阵本身的大小因图像的不同而不同,通常是较大的数量级。因此,当你在您的程序中传递图像并在有些时候创建图像副本您需要花费很大的代价生成图像矩阵本身,而不是图像的头部。OpenCV 是图像处理库,它包含大量的图像处理函数。若要解决的计算挑战,最终大部分时间你会使用库中的多个函数。由于这一原因图像传给库中的函数是一种常见的做法。我们不应忘记我们正在谈论往往是计算量相当大的图像处理算法。我们想要做的最后一件事是通过制作不必要的可能很大的图像的拷贝进一步降低您的程序的速度。

先看代码:

#include <opencv2/opencv.hpp>
using namespace cv;

void main() {
    Mat img1 = imread("E:\\VS2015Opencv\\vs2015\\project\\picture\\01.jpg");
    namedWindow("原图像", WINDOW_AUTOSIZE);
    imshow("原图像", img1);
    Mat img2(img1);
    Mat img3 = img1;
    Mat img4 = img1.clone();
    Mat img5;
    img1.copyTo(img5);

    cvtColor(img1, img1, CV_BGR2HSV);//BGR图转为HSV图
    imshow("img1转为HSV", img1);
    imshow("img2", img2);
    imshow("img3", img3);//image1/2/3跟随原图变化
    imshow("img4", img4);
    imshow("img5", img5);//image4/5不会跟随原图变化
    waitKey(0);
}

首先这段函数很常用,试比较

     Mat image1 = imread("test.png",IMREAD_COLOR);
     Mat image2 =( image1);

     Mat img3 = img1;


此时,image3,image2得到的是image1的一个引用,是一种基于浅拷贝策略的赋值,即image2实际上指向的是image1的内存单元。当image1提前被释放掉的时候,image2访问无效。

所以2,3会随着1的改变而改变;

如果想要复制image1的数据内容,而不仅仅是指向,那么就需要用clone 函数 ,该函数实现的是“深拷贝”,能够把Mat的数据单元复制给其他对象,比如:

      Mat image1 = imread("test.png",IMREAD_COLOR);
      Mat image2 = image1.clone();
此时image2不再受限于image1的状态,可以自由操作。

所以img4是复制image1的数据内容,而不仅仅是指向,并不会随着img1的改变而改变;
实际上,OpenCV 对于Mat的的= 的赋值构造函数并没有做太多的修改,我们通过该赋值构造函数得到的只是一个引用。

      Mat img1 = imread("E:\\VS2015Opencv\\vs2015\\project\\picture\\01.jpg");
      namedWindow("原图像", WINDOW_AUTOSIZE);
      imshow("原图像", img1);
      Mat img4 = img1.clone();
      Mat img5;
      img1.copyTo(img5);

同样的,对于copyTo韩式是从img1矩阵复制data数据单元,与clone函数的作用类似,使用形式不同;,image5和image1具有同样的数据内容,同时,不受限于image1的状态。

官网

Mat函数十分庞大,其所涉及的成员函数和变量难以一一细数,在这里,仅学习记录其最最最常见的部分,以便日常使用。

本文后面成员函数参考博文:https://www.cnblogs.com/long5683/p/9693014.html

 

posted @ 2019-07-29 14:40  浮沉沉浮  阅读(1929)  评论(0编辑  收藏  举报