• OpenCV For Unity Mat容器的创建与矩阵操作基础


    Mat的概念

    Mat是在OpenCV里最基础的一个概念,他在数学上的形式可以表现为一个N*M的矩阵。

     

    一个3X3的矩阵

    今天就要来记录一下最基础的矩阵操作:

    建立一个矩阵(Mat)

    申明一个矩阵的代码是,跟你初始化一个对象的实例,很相似。

    Mat m = new Mat(3,3,CvType,CV_8UC1); 
    

    他一共可以传入3个参数(int row,int col,cvtype)

    前面两个传入的行数与列数,定义这个矩阵的大小,3行3列 说明一共有9个元素。

    而后面需要传入一个CvType的类型,定义了矩阵里每个元素能表示的数字大小。

     

    cvtype可以定义的类型

    而例如是8UC1代表了什么呢?
    8是代表这个值的大小,他可以表示2^8即能表示256个数,如果是无符号的正数,他的范围为0~255。
    如果是有符号的负数的情况就是-127~127
    而有没有符号即用后面的U来决定,
    U-unsign int 即无符号的正整数
    S-sign int 即有符号的的整数(正负整数)
    F-float 即为单精度的浮点数
    C则指的是通道数
    C1 则是1通道 一般是灰度图像
    C3 则是3通道 一般是含有RGB三通道的彩色图像
    C4 则是含有Alpha通道的4四通道的图像。

    矩阵的打印

    你可以通过

    Mat.Dump()
    

    把矩阵输出到控制台,注意建议不要输出太大型的矩阵,经常容易卡死。

    矩阵的初始化

    矩阵的初始化,你可以通过Mat.put()来输入数值。

     

    矩阵的初始化之一

    1. Mat mat1 = new Mat(3, 3, CvType.CV_8SC1);
    2. mat1.put(0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
    3. //前面两个参数定义输入输入的起始位置,这里就表示从第一个位置开始,
    4. //依次输入012345....
    5. // 如果填写参数的少于实际的元素,其他会被0填充
    6. //如果大于,多的会被忽略
    7. Debug.Log ("mat1=" + mat1.dump ());

     

     

    输出到控制台的结果

    那你会想如果我矩阵小还好,如果我矩阵是100X100,那不得填到天荒地老去啦?

    快速填充矩阵的方法

    那我们来看快速填充矩阵的方法

    1. Mat mat2 = new Mat (3, 3, CvType.CV_8UC1, new Scalar (300));
    2. Debug.Log ("mat2=" + mat2.dump ());

    你在创立Mat的时候最后可以传入一个Scalar的对象,他是控制规模,比如传入new scalar,他矩阵里所有元素都会被填为300

    最后为输出的结果为:

     

    第二个填充方法

    你会想你上面代码不是输入的new Scalar(300)嘛,为什么最后输出结果全是255,这就验证了我们之前定义的矩阵的CVTYPE为8UC1,他只能表示0-255的数,如果你想要表示300,你就必须把申请的矩阵大小翻倍,申请为16UC1,这个一定要在之后的矩阵运算中注意一下。

    你也可以通过

    1. Mat.ones()
    2. Mat.zeros()
    3. Mat.eyes()

    分别创建一个全为1的矩阵,创建一个全为0的函数,创建一个对角线的矩阵

     全为1的矩阵

    全为0的矩阵

    随机矩阵

    我们有时候可能需要一个随机的矩阵,请用:

    Core.randu(Mat dst,double low,double high);
    

     随机填充一个矩阵

    参数分别代表:需要填充的矩阵,随机的最低与最高值,在这个区间内产生数字。

    1. Mat mat7 = new Mat (3, 2, CvType.CV_8UC1);
    2. Core.randu (mat7, 0, 256);
    3. Debug.Log ("mat7=" + mat7.dump ());

    随机矩阵的结果

     

    也可以通过

    Core.randn(Mat dst,double mean,double sstdev)
    

    第一个参数是需要随机的矩阵,第二参数是种子数(基准数,将在这个数为基础进行随机),第三个参数是范围,比如传5,将在第二数的基础上加减5 的范围内进行随机。

    1. Mat mat8 = new Mat (3, 2, CvType.CV_8UC1);
    2. Core.randn (mat8, 128, 10);
    3. Debug.Log ("mat8=" + mat8.dump ());

     

    最后的结果在128的+-10的范围内随机

    特殊形状的矩阵

    有时候你可能会需要一个特殊形状的矩阵,这时候你就要借助下面这个函数来建立矩阵!

    Imgproc.getStructuringElement(int shape,size ksize);
    

    第一个参数在Imgproc这个类里提供了对应的枚举类型;
    第二个参数这是Size对应多少行(row),多少列(column);

    这个函数将返回一个Mat容器,你可以通过Mat.dump(),打印到控制台来帮助自己学习理解。

    下面我将举例一下一些常用的矩阵

    • Imgproc.MORPH_CROSS 是一个十字形
    1. var es = Imgproc.getStructuringElement(Imgproc.MORPH_CROSS, new Size(7, 5));
    2. Debug.Log(es.dump());

    5行7列的Cross

     

    • Imgproc.MORPH_ELLIPSE 是一个椭圆

    •  

      5行7列的椭圆型

    • Imgproc.MORPH_RECT 是一个7列5行的矩形,其实他相当于等价Mat.ones(5, 7, CvType.CV_8UC1);

    5行7列的矩形

     

    常用的便是以上几种,你可以再Unity中还提供了几个其他枚举,你可以自己打印看看。

    以上就是矩阵里的一些操作



     
    链接:https://www.jianshu.com/p/584c9d71198d

  • 相关阅读:
    策略模式在应用中的实践
    用Dockerfile引入镜像报错
    HarmonyOs开发:组件如何实现属性的动态设置
    【正则】二代身份证正则表达式
    http协议(序列化与反序列化)
    【Mongoose笔记】HTTP 客户端
    详解mybatis三种分页方式
    JavaSE编程题目练习(三)
    FPGA常用通信协议 —UART(二)---UART接收
    如何从 FastReport VCL 中将报表导出为PNG格式?
  • 原文地址:https://blog.csdn.net/qq_42672770/article/details/127663922