Mat

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等,也有一些调试的时候经常遇到的,这里放在一起统一整理一下。

  • data 指向矩阵数据部分的指针

  • rows 矩阵的行数

  • cols 矩阵的列数

  • dims 矩阵的维度,二维矩阵dims=2,三维矩阵dims=3.

  • size 矩阵的大小,size(cols,rows),如果矩阵的维数大于2,则是size(-1,-1)

  • channels 矩阵元素拥有的通道数,例如常见的彩色图像,每一个像素由RGB三部分组成,则channels = 3

  • type 用于表示矩阵中元素存储类型的预定义的常量,其本质是特殊命名规则下的int类型常量,其命名规则为CV_(位数)+(数据类型)+(通道数)。
    数据类型包括这里U(unsigned integer)表示的是无符号整数,S(signed integer)是有符号整数,F(float)是浮点数。
    例如:CV_16UC2,表示的是元素类型是一个16位的无符号整数,通道为2。
    C1,C2,C3,C4则表示通道是1,2,3,4

  • depth
    矩阵中元素的一个通道的数据类型,这个值和type是相关的。例如 type为 CV_16SC2,一个2通道的16位的有符号整数。那么,depth则是CV_16S。depth也是一系列的预定义值,
    将type的预定义值去掉通道信息就是depth值:
    CV_8U CV_8S CV_16U CV_16S CV_32S CV_32F CV_64F

  • elemSize
    矩阵一个元素占用的字节数,例如:type是CV_16SC3,那么elemSize = 3 * 16 / 8 = 6 bytes

  • elemSize1
    矩阵元素一个通道占用的字节数,例如:type是CV_16CS3,那么elemSize1 = 16 / 8 = 2 bytes = elemSize / channels

  • step
    step[0]是矩阵中一行元素的字节数。
    step[1]是矩阵中一个元素的字节数,也就是和上面所说的elemSize相等。

    上面说到,Mat中一个uchar* data指向矩阵数据的首地址,而现在又知道了每一行和每一个元素的数据大小,就可以快速的访问Mat中的任意元素了。下面公式:


    TIM截图20180717231815.png

  • step1
    规整化的step,值为step / elemSize1。 定义如下:
inline size_t Mat::step1(int i) const { return step.p[i]/elemSize1(); }

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


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

未完待续

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容