java
Mat可以保存图片。图片RGB-是三通道,所以Mat也包含了通道数。
列举最常见的一些方法
创建
Mat mat = new Mat(3,2, CvType.CV_32SC3);
第一二个参数是行列数,第三个参数是mat的类型。这里32SC3表示一个像素用了32位,S代表signed int,C3代表通道数是3。
即 创建一个3X2的矩阵,此矩阵具有3通道。每个点能保存int类型数据
未带通道数的默认是1。例如,CV_8U就等同于CV_8UC1,CV_32S就等同于CV_32SC1。
更常用的是Mat mat = Imgcodecs.imread();
理解如何保存
这是我不理解的地方,着力于此
Mat mat = new Mat(3,2, CvType.CV_32SC3);
System.out.println(mat.dump());//数据矩阵的所有元素
输出如下:
3行2列。2列就是红色矩形框。一行三个元素是因为三个通道。
详细看下面的代码。
Mat mat = new Mat(2, 2, CvType.CV_32SC3);
int[] tep=new int[]{1,2,3,4,5,6,7,8,9,10,11,12};
mat.put(0,0,tep); //按照顺序放
System.out.println(mat.dump());
ArrayList<Mat> channels = new ArrayList<>();
Core.split(mat,channels);//split函数是分离channel
System.out.println(channels.get(0).dump());
int[] tmp=new int[3];
mat.get(1,1,tmp);
for (int i = 0; i <tmp.length; i++) {
System.out.print(tmp[i]);
}
可以看到,第一个channel里面的值是[1,4,7,10].
channels[0] =
[ 1, 4;
7, 10]
channels[1] =
[ 2, 5;
8, 11]
channels[2] =
[ 3, 6;
9, 12]
化成下图:颜色不同代表不同Channel
将三个颜色(犹如RGB)的数放在一起,不就是2行2列吗?
足以说明这样理解是没有错误的
Mat mat = new Mat(3,2, CvType.CV_32SC3,new Scalar(1,2,4));
System.out.println(mat.dump());
下面均已这个例子举例。
get
get(行,列)或者get(行,列,数组)
注意这里的数组必须是channel的整数倍。
这样也说明,如果数组足够大,get(0,0,数组)足以获得所有元素
通俗来说:我从(0,0)开始获取元素,数组多大我就能得到多少元素
Mat mat = new Mat(3,2, CvType.CV_32SC3,new Scalar(1,2,4));
System.out.println(mat.dump());
System.out.println(mat.get(0,1)[0]);//第一行,第二列,通道1的元素:1
System.out.println(mat.get(0,1)[1]);//第一行,第二列,通道2的元素:2
System.out.println(mat.get(0,2)[0]);// 数组出界
put
放进去的数组大小需要是通道数的倍数。满足此前提下,会依次将数组里的元素放进矩阵里面。
能放多少放多少
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat mat = new Mat(3,2, CvType.CV_32SC3,new Scalar(1,2,4));
System.out.println(mat.dump());
System.out.println(mat.get(0,1)[0]);
System.out.println(mat.get(0,1)[1]);
int[] am=new int[]{4,5,6};
mat.put(1,1,am);
System.out.println(mat.dump());
System.out.println(mat.get(1,1)[1]);
push_back
新添加的Mat和原来的Mat,需要列数,通道数相同。
mat.push_back(new Mat(4,2,CvType.CV_32SC3,new Scalar(0,0,0)));
System.out.println(mat.dump());
reshape
双参,第一个是通道数,第二个是行数。如果为0,新的矩阵和原矩阵的通道/行数相同。
无论怎么变,新矩阵的元素个数不变。
//reshape
Mat a=mat.reshape(2,1);
System.out.println(a.dump());
System.out.println(a.rows());
System.out.println(a.cols());
System.out.println(a.channels());
convertTo
convertTo可以改变Mat的深度,例如可以把Mat的type从CV_8UC3改为CV_16SC3
convertTo不可以改变Mat的通道数,例如不可以把Mat的type从CV_8UC3改为CV_8UC1,即使你填入的转换类型通道数不同,输出的通道数还是与输入的通道数相同。(https://blog.csdn.net/a435262767/article/details/90522073)
可以先 reshape,改变通道数,再用convertTo改变深度