Mat

2018-07-17  本文已影响0人  tiyife

Mat的基本介绍

基本上讲 Mat 是一个类,由两个数据部分组成:

Mat 的传递

Mat中的矩阵头相比于存储像素值的矩阵而言非常小,所以在Mat的传递过程中通常传递的是Mat的矩阵头。每一个Mat拥有自己的矩阵头,但是不同的Mat共享一个像素值矩阵,矩阵维护一个引用次数,每拷贝一次Mat对象,矩阵的引用次数就会加一,反之矩阵头被释放时计数减一,最后一个引用的矩阵头负责释放掉矩阵。

Mat A, C;                                 // 只创建矩阵头
A = imread(argv[1], CV_LOAD_IMAGE_COLOR); // 这里为矩阵开辟内存
Mat B(A);                                 // 拷贝A的矩阵头
C = A;                                    // 拷贝A的矩阵头
Mat D (A, Rect(10, 10, 100, 100) ); // 创建一个新的矩阵头,并指向A的矩阵
Mat E = A(Range:all(), Range(1,3)); // 创建一个新的矩阵头,并指向A的矩阵s

上述方法都是通过拷贝矩阵头的方法来实现Mat的传递,当用户想要拷贝整个矩阵的时候可以通过copyto()和clone()来实现。

    Mat image = imread("2.jpg");
    resize(image, image, Size(), 0.5, 0.5);

    Mat image1(image) ;//仅是创建了Mat的头部分,image1与image共享数据区
    Mat image2 = image ;//仅是创建了Mat的头部分,image1与image共享数据区
    Mat image3 = image.clone() ;//完全拷贝,把image中的所有信息拷贝到image3中
    Mat image4;
    image.copyTo(image4);//根据image信息创建新的矩阵头,并拷贝image的数据区到image1中
    
    for (int i = 0; i < image.rows; ++i)
    {
        uchar* ptr = image.ptr(i);
        for (int j = 0; j < image.cols; ++j)
        {
            ptr[j] = 0;
        }
    }
    imshow("image", image);
    imshow("image1", image1);
    imshow("image2", image2);
    imshow("image3", image3);
    imshow("image4", image4);
    waitKey();
    return 0;

上述代码运行后结果如下图,可见修改了image的数据区之后iamge1和image2都随着发生变化了,而image3和image4仍保持着原图的样子。


图片.png

Mat 的常用属性

Mat有很多属性,有一些我经常用的如rows、cols、dims和channels等,也有一些调试的时候经常遇到的,这里放在一起统一整理一下。

inline size_t Mat::step1(int i) const { return step.p[i]/elemSize1(); }

以CV16UC4的img为例,来看下step,step1具体的值:

image
img的type是CV_16UC4, step[0]是其一行所占的数据字节数4 *4 * 16 / 8 = 32
step[1] 是一个元素所占的字节数,img的一个元素具有4个通道,故:4 * 16 / 8 = 8
step1 = step / elemSize1,elemSize1是元素的每个通道所占的字节数。

未完待续

上一篇下一篇

猜你喜欢

热点阅读