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的类型,定义了矩阵里每个元素能表示的数字大小。

OpenCV For Unity Mat容器的创建与矩阵操作基础_第1张图片
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()来输入数值。

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

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

快速填充矩阵的方法

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

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

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

最后为输出的结果为:

第二个填充方法

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

你也可以通过

Mat.ones() 
Mat.zeros() 
Mat.eyes()

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

全为1的矩阵
全为0的矩阵
随机矩阵

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

Core.randu(Mat dst,double low,double high);
随机填充一个矩阵

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

 Mat mat7 = new Mat (3, 2, CvType.CV_8UC1);
Core.randu (mat7, 0, 256);
Debug.Log ("mat7=" + mat7.dump ());
随机矩阵的结果

也可以通过

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

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

Mat mat8 = new Mat (3, 2, CvType.CV_8UC1);
Core.randn (mat8, 128, 10);
Debug.Log ("mat8=" + mat8.dump ());
最后的结果在128的+-10的范围内随机
特殊形状的矩阵

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

Imgproc.getStructuringElement(int shape,size ksize);

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

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

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

  • Imgproc.MORPH_CROSS 是一个十字形
var es = Imgproc.getStructuringElement(Imgproc.MORPH_CROSS, new Size(7, 5));
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中还提供了几个其他枚举,你可以自己打印看看。

以上就是矩阵里的一些操作,你熟悉了这个容器Mat,你才能更好的去学习Opencv

你可能感兴趣的:(OpenCV For Unity Mat容器的创建与矩阵操作基础)