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()来输入数值。
矩阵的初始化之一
- 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(),打印到控制台来帮助自己学习理解。
下面我将举例一下一些常用的矩阵
- 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中还提供了几个其他枚举,你可以自己打印看看。
以上就是矩阵里的一些操作
链接:https://www.jianshu.com/p/584c9d71198d