对初学者来说,我们总是希望通过Opencv实现一些功能,当我们去研究一个陌生的东西,我们总是想着利用他去实现某一个功能
比如Opencv,我们很容易利用他去进行人脸识别,人脸识别也有很多的方式比如利用opecv自带的算法:
但是这对我们来说仅仅是皮毛,也是opencv用来检验的测试用例
我们不能拿它做出什么东西,甚至我们连人物识别都不知道怎样做,我们学习新的知识,不能仅仅做知识的搬运工,我们应该从砌砖开始,而不是一开始就研究整个屋子
人脸识别opencv还支持DNN,但是我在使用pb模型的时候,最后forward输出的矩阵我并不知道怎么处理来显示出来图像,所以不得用时间将基础做好,opencv java里面有一个重要的类是Mat,那么我们先看看如何创建
废话少说,看源代码
public Mat(long addr) {
if (addr == 0)
throw new UnsupportedOperationException("Native object address is NULL");
nativeObj = addr;
}
//
// C++: Mat::Mat()
//
// javadoc: Mat::Mat()
public Mat() {
nativeObj = n_Mat();
}
//
// C++: Mat::Mat(int rows, int cols, int type)
//
// javadoc: Mat::Mat(rows, cols, type)
public Mat(int rows, int cols, int type) {
nativeObj = n_Mat(rows, cols, type);
}
//
// C++: Mat::Mat(int rows, int cols, int type, void* data)
//
// javadoc: Mat::Mat(rows, cols, type, data)
public Mat(int rows, int cols, int type, ByteBuffer data) {
nativeObj = n_Mat(rows, cols, type, data);
}
//
// C++: Mat::Mat(int rows, int cols, int type, void* data, size_t step)
//
// javadoc: Mat::Mat(rows, cols, type, data, step)
public Mat(int rows, int cols, int type, ByteBuffer data, long step) {
nativeObj = n_Mat(rows, cols, type, data, step);
}
//
// C++: Mat::Mat(Size size, int type)
//
// javadoc: Mat::Mat(size, type)
public Mat(Size size, int type) {
nativeObj = n_Mat(size.width, size.height, type);
}
//
// C++: Mat::Mat(int ndims, const int* sizes, int type)
//
// javadoc: Mat::Mat(sizes, type)
public Mat(int[] sizes, int type) {
nativeObj = n_Mat(sizes.length, sizes, type);
}
//
// C++: Mat::Mat(int rows, int cols, int type, Scalar s)
//
// javadoc: Mat::Mat(rows, cols, type, s)
public Mat(int rows, int cols, int type, Scalar s) {
nativeObj = n_Mat(rows, cols, type, s.val[0], s.val[1], s.val[2], s.val[3]);
}
//
// C++: Mat::Mat(Size size, int type, Scalar s)
//
// javadoc: Mat::Mat(size, type, s)
public Mat(Size size, int type, Scalar s) {
nativeObj = n_Mat(size.width, size.height, type, s.val[0], s.val[1], s.val[2], s.val[3]);
}
//
// C++: Mat::Mat(int ndims, const int* sizes, int type, Scalar s)
//
// javadoc: Mat::Mat(sizes, type, s)
public Mat(int[] sizes, int type, Scalar s) {
nativeObj = n_Mat(sizes.length, sizes, type, s.val[0], s.val[1], s.val[2], s.val[3]);
}
//
// C++: Mat::Mat(Mat m, Range rowRange, Range colRange = Range::all())
//
// javadoc: Mat::Mat(m, rowRange, colRange)
public Mat(Mat m, Range rowRange, Range colRange) {
nativeObj = n_Mat(m.nativeObj, rowRange.start, rowRange.end, colRange.start, colRange.end);
}
// javadoc: Mat::Mat(m, rowRange)
public Mat(Mat m, Range rowRange) {
nativeObj = n_Mat(m.nativeObj, rowRange.start, rowRange.end);
}
//
// C++: Mat::Mat(const Mat& m, const std::vector& ranges)
//
// javadoc: Mat::Mat(m, ranges)
public Mat(Mat m, Range[] ranges) {
nativeObj = n_Mat(m.nativeObj, ranges);
}
//
// C++: Mat::Mat(Mat m, Rect roi)
//
// javadoc: Mat::Mat(m, roi)
public Mat(Mat m, Rect roi) {
nativeObj = n_Mat(m.nativeObj, roi.y, roi.y + roi.height, roi.x, roi.x + roi.width);
}
我数一下,大概有十几个构造方法,我们可以简单的立即这个方法就是用来创建一个矩阵
那么一个矩阵需要什么,多少行,多少列,以及元素值(初始化)
Mat其实是描述图像的,比我们数学中的矩阵要多一个参数,类型和通道
通道: 有单通道,3通道,和四通道,类型:有符号和无符号
最简单的,我们用Mat mat=new Mat();看看得到结果是什么
可以看到创建的默认的是单通道的,而且矩阵里面没有任何的元素
我们从简单的矩阵2*2的矩阵开始创建
发现了什么,我们可以用一个Mat 创建其他的Mat,而且我们创建Mat时候只要传递参数类型是必须传递的,上面的不传递参数的我们看到的创建Mat默认的type是0 ,那么0标识什么
一共有8中类型
U标识无符号,S标识有符号,F 标识有符号的Float
默认创建的0是8位无符号的,并且是0行0列的单通道矩阵
了解了类型,我们继续创建我们的2*2的矩阵,那么我们看无符号的吧:
我们看到2*2的矩阵,里面的数据是随机产生的,默认的是单通道
如果我们不想让数据随机产生,我们可以进行初始化
new Scalar()这个是通道赋值,在opencv中的作用是颜色作用,我们知道颜色表示方法很多,有十六进制的#fffff 还有RGB(0,0,255) 这个地方Scalar其实很RGB很接近,但是单通道的话,只需要一个值,第二个值是不生效的
3通道的话是是需要三个值,当然你也可以两个值,最后的默认为0 4通道类似,
可能说的不太好理解,我们几个例子
我们看到的是2在创建矩阵的时候并没有啥作用,那么多颜色有作用我们
我们将Mat转换为图片显示出来看看
我们改变new Scalar(1,2),修改成为new Scalar(1,125)
修改成为new Scalar(1,255)
没有变化,也就是说第二个参数不起作用
那么第一个参数用什么作用
当我们从1调整到125的时候,灰度变化了,或者最直观的是没有那么黑了
那么我们继续调整到254
接近于白色
在这个地方我们可以看单通道的是创建的灰度化图片
我们创建2通道的,看看回事怎么样
如何创建2通道的:
双通道,我们可以看到的是矩阵的元素,是很new Scalar(254,255)对应起来的
第一个和Scalar的第一个参数一样,第二个和Scalar的第二个元素一样
为什么上面的数据都是正数,无符号,就是数据前面都是没有符号的,如果非要new Scalar(-1,255)
满足了吗,当小于0的时候就自动变成0了
双通道的图片是怎样的,我们不仅的好奇
我们用下面几个参数来标识
new Saclar(0,0) new Saclar(1,125) new Saclar(1,255)
new Scalar(125,125) new Scalar(255,125) new Scalar(255,255)
双通道的图片我们可以到的是无论是第一个参数变化,还是第二个参数编号都对整个图片有影响
但是双通道的图片研究起来好像没有多大的意思,其实黑白+灰度,而且整个图片上下都不一样
所以,双通道的到此为止
我们来看三通道的图片:
new Scalar这个时候需要三个值进行描述
这样好像就清晰了,RGB
我们看几个图片
我们知道new Scalar有最多有4参数,最后一个表示什么
第4参数标识图片的透明度,在0-1之间
今天好像说的有点跑题,我们大概知道了new Scalar()里面参数的含义
并且知道了创建矩阵,通道,初始化赋值
通过上面的例子,希望你对mat有更多的理解,如果有什么不对还请多多指教
希望对你有所帮助