zoukankan      html  css  js  c++  java
  • 『OpenCV3』Mat简介

    Mat属性方法介绍:OpenCV2:Mat属性type,depth,step

    推荐一套OpenCV入门博客:OpenCV探索

    一、Mat

    Mat类用于表示一个多维的单通道或者多通道的稠密数组。能够用来保存实数或复数的向量、矩阵,灰度或彩色图像,立体元素,点云,张量以及直方图(高维的直方图使用SparseMat保存比较好)。简而言之,Mat就是用来保存多维的矩阵的

    Mat存储

    Mat分为头信息和数组body两部分,头信息声明后即创建,body需要调用create方法或者其他方法后才划取内存创建。由于图片含有通道这一特性,所以其存储可以描述成,假设一幅图,它的通道数为i,大小为a*b,则存储成数字矩阵形式,则为一个行数为a,列数为b*i大小的矩阵,而对应行,i个通道的值是顺序穿插的。

    Mat类型

    type

    表示了矩阵中元素的类型以及矩阵的通道个数,它是一系列的预定义的常量,其命名规则为CV_(位数)+(数据类型)+(通道数)。具体的有以下值:

    CV_8UC1 CV_8UC2 CV_8UC3 CV_8UC4
    CV_8SC1 CV_8SC2 CV_8SC3 CV_8SC4
    CV_16UC1 CV_16UC2 CV_16UC3 CV_16UC4
    CV_16SC1 CV_16SC2 CV_16SC3 CV_16SC4
    CV_32SC1 CV_32SC2 CV_32SC3 CV_32SC4
    CV_32FC1 CV_32FC2 CV_32FC3 CV_32FC4
    CV_64FC1 CV_64FC2 CV_64FC3 CV_64FC4

    这里U(unsigned integer)表示的是无符号整数,S(signed integer)是有符号整数,F(float)是浮点数。
    例如:CV_16UC2,表示的是元素类型是一个16位的无符号整数,通道为2.
    C1,C2,C3,C4则表示通道是1,2,3,4
    type一般是在创建Mat对象时设定,如果要取得Mat的元素类型,则无需使用type,使用depth属性。

    我们实际查询时返回的都是一个整数而非上面的字符串,看看opencv源码:

    #define CV_CN_MAX     512
    #define CV_CN_SHIFT   3
    #define CV_DEPTH_MAX  (1 << CV_CN_SHIFT)
    
    #define CV_8U   0
    #define CV_8S   1
    #define CV_16U  2
    #define CV_16S  3
    #define CV_32S  4
    #define CV_32F  5
    #define CV_64F  6
    #define CV_USRTYPE1 7
    
    #define CV_MAT_DEPTH_MASK       (CV_DEPTH_MAX - 1)
    #define CV_MAT_DEPTH(flags)     ((flags) & CV_MAT_DEPTH_MASK)
    
    #define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))
    #define CV_MAKE_TYPE CV_MAKETYPE
    
    #define CV_8UC1 CV_MAKETYPE(CV_8U,1)
    #define CV_8UC2 CV_MAKETYPE(CV_8U,2)
    #define CV_8UC3 CV_MAKETYPE(CV_8U,3)
    #define CV_8UC4 CV_MAKETYPE(CV_8U,4)
    #define CV_8UC(n) CV_MAKETYPE(CV_8U,(n))
    
    #define CV_8SC1 CV_MAKETYPE(CV_8S,1)
    #define CV_8SC2 CV_MAKETYPE(CV_8S,2)
    #define CV_8SC3 CV_MAKETYPE(CV_8S,3)
    #define CV_8SC4 CV_MAKETYPE(CV_8S,4)
    #define CV_8SC(n) CV_MAKETYPE(CV_8S,(n))
    
    #define CV_16UC1 CV_MAKETYPE(CV_16U,1)
    #define CV_16UC2 CV_MAKETYPE(CV_16U,2)
    #define CV_16UC3 CV_MAKETYPE(CV_16U,3)
    #define CV_16UC4 CV_MAKETYPE(CV_16U,4)
    #define CV_16UC(n) CV_MAKETYPE(CV_16U,(n))
    
    #define CV_16SC1 CV_MAKETYPE(CV_16S,1)
    #define CV_16SC2 CV_MAKETYPE(CV_16S,2)
    #define CV_16SC3 CV_MAKETYPE(CV_16S,3)
    #define CV_16SC4 CV_MAKETYPE(CV_16S,4)
    #define CV_16SC(n) CV_MAKETYPE(CV_16S,(n))
    
    #define CV_32SC1 CV_MAKETYPE(CV_32S,1)
    #define CV_32SC2 CV_MAKETYPE(CV_32S,2)
    #define CV_32SC3 CV_MAKETYPE(CV_32S,3)
    #define CV_32SC4 CV_MAKETYPE(CV_32S,4)
    #define CV_32SC(n) CV_MAKETYPE(CV_32S,(n))
    
    #define CV_32FC1 CV_MAKETYPE(CV_32F,1)
    #define CV_32FC2 CV_MAKETYPE(CV_32F,2)
    #define CV_32FC3 CV_MAKETYPE(CV_32F,3)
    #define CV_32FC4 CV_MAKETYPE(CV_32F,4)
    #define CV_32FC(n) CV_MAKETYPE(CV_32F,(n))
    
    #define CV_64FC1 CV_MAKETYPE(CV_64F,1)
    #define CV_64FC2 CV_MAKETYPE(CV_64F,2)
    #define CV_64FC3 CV_MAKETYPE(CV_64F,3)
    #define CV_64FC4 CV_MAKETYPE(CV_64F,4)
    #define CV_64FC(n) CV_MAKETYPE(CV_64F,(n))
    

    实际上有如下8个类型:

    #define CV_8U   0
    #define CV_8S   1
    #define CV_16U  2
    #define CV_16S  3
    #define CV_32S  4
    #define CV_32F  5
    #define CV_64F  6
    #define CV_USRTYPE1 7
    

    即单通道时,这些编号即是这些声明的值。然后若是2个通道,则加上8;3个通道,则加上16;4个通道则加上24。

    原因是

    #define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))
    

    先不看前边的部分,cn - 1 << CV_CNSHIFT即将通道数-1再移3位。(CV_CN_SHIFT值为3)

    前边的看起来虽然是嵌套了声明,实际上也并不是很复杂。其实就是8个编号分别与7进行与操作,当然在当前看到的这些情况下,其实就是原值。

    一句话总结这些声明,就是:声明的值 = 数据类型的编号 + (通道数 - 1) * 8

    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

    二、Mat常见方法属性

    Mat常规方法

    Mat信息查询

    Mat元素访问

    从Mat创建子Mat

  • 相关阅读:
    监控服务器配置(一)-----Prometheus安装配置
    mongo可视化工具adminMongo安装
    Grafana 下载与安装(v5.4.1)
    Grafana+Prometheus系统监控之Redis
    聊聊redis的监控工具
    Linux 服务器buff/cache清理
    redis为什么内存不宜过大
    Python 操作 mongodb 亿级数据量使用 Bloomfilter 高效率判断唯一性 例子
    Redis-3.2.0集群配置(redis cluster)
    在reshard过程中,将会询问reshard多少slots:
  • 原文地址:https://www.cnblogs.com/hellcat/p/9243478.html
Copyright © 2011-2022 走看看