java OpenCv Mat 类的基本操作(3)

对初学者来说,我们总是希望通过Opencv实现一些功能,当我们去研究一个陌生的东西,我们总是想着利用他去实现某一个功能

比如Opencv,我们很容易利用他去进行人脸识别,人脸识别也有很多的方式比如利用opecv自带的算法:

java OpenCv Mat 类的基本操作(3)_第1张图片

但是这对我们来说仅仅是皮毛,也是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();看看得到结果是什么

java OpenCv Mat 类的基本操作(3)_第2张图片

可以看到创建的默认的是单通道的,而且矩阵里面没有任何的元素 

我们从简单的矩阵2*2的矩阵开始创建

java OpenCv Mat 类的基本操作(3)_第3张图片

发现了什么,我们可以用一个Mat 创建其他的Mat,而且我们创建Mat时候只要传递参数类型是必须传递的,上面的不传递参数的我们看到的创建Mat默认的type是0 ,那么0标识什么

java OpenCv Mat 类的基本操作(3)_第4张图片

一共有8中类型

U标识无符号,S标识有符号,F 标识有符号的Float

默认创建的0是8位无符号的,并且是0行0列的单通道矩阵

了解了类型,我们继续创建我们的2*2的矩阵,那么我们看无符号的吧:

java OpenCv Mat 类的基本操作(3)_第5张图片

我们看到2*2的矩阵,里面的数据是随机产生的,默认的是单通道

如果我们不想让数据随机产生,我们可以进行初始化

java OpenCv Mat 类的基本操作(3)_第6张图片

new Scalar()这个是通道赋值,在opencv中的作用是颜色作用,我们知道颜色表示方法很多,有十六进制的#fffff 还有RGB(0,0,255) 这个地方Scalar其实很RGB很接近,但是单通道的话,只需要一个值,第二个值是不生效的

3通道的话是是需要三个值,当然你也可以两个值,最后的默认为0 4通道类似,

可能说的不太好理解,我们几个例子

java OpenCv Mat 类的基本操作(3)_第7张图片

 

我们看到的是2在创建矩阵的时候并没有啥作用,那么多颜色有作用我们

我们将Mat转换为图片显示出来看看

java OpenCv Mat 类的基本操作(3)_第8张图片

 

我们改变new Scalar(1,2),修改成为new Scalar(1,125)

java OpenCv Mat 类的基本操作(3)_第9张图片

 

修改成为new Scalar(1,255)

java OpenCv Mat 类的基本操作(3)_第10张图片

没有变化,也就是说第二个参数不起作用

那么第一个参数用什么作用

java OpenCv Mat 类的基本操作(3)_第11张图片

当我们从1调整到125的时候,灰度变化了,或者最直观的是没有那么黑了

那么我们继续调整到254

java OpenCv Mat 类的基本操作(3)_第12张图片

 接近于白色

在这个地方我们可以看单通道的是创建的灰度化图片

我们创建2通道的,看看回事怎么样

如何创建2通道的:

java OpenCv Mat 类的基本操作(3)_第13张图片

双通道,我们可以看到的是矩阵的元素,是很new Scalar(254,255)对应起来的

第一个和Scalar的第一个参数一样,第二个和Scalar的第二个元素一样

为什么上面的数据都是正数,无符号,就是数据前面都是没有符号的,如果非要new Scalar(-1,255)

java OpenCv Mat 类的基本操作(3)_第14张图片

满足了吗,当小于0的时候就自动变成0了

双通道的图片是怎样的,我们不仅的好奇

我们用下面几个参数来标识

          new Saclar(0,0)                   new Saclar(1,125)                      new Saclar(1,255)                   

java OpenCv Mat 类的基本操作(3)_第15张图片java OpenCv Mat 类的基本操作(3)_第16张图片java OpenCv Mat 类的基本操作(3)_第17张图片   

       new Scalar(125,125)             new Scalar(255,125)                 new Scalar(255,255)

java OpenCv Mat 类的基本操作(3)_第18张图片java OpenCv Mat 类的基本操作(3)_第19张图片java OpenCv Mat 类的基本操作(3)_第20张图片

 双通道的图片我们可以到的是无论是第一个参数变化,还是第二个参数编号都对整个图片有影响

但是双通道的图片研究起来好像没有多大的意思,其实黑白+灰度,而且整个图片上下都不一样

所以,双通道的到此为止

我们来看三通道的图片:

java OpenCv Mat 类的基本操作(3)_第21张图片

new Scalar这个时候需要三个值进行描述

java OpenCv Mat 类的基本操作(3)_第22张图片

这样好像就清晰了,RGB

我们看几个图片

java OpenCv Mat 类的基本操作(3)_第23张图片

我们知道new Scalar有最多有4参数,最后一个表示什么

java OpenCv Mat 类的基本操作(3)_第24张图片

java OpenCv Mat 类的基本操作(3)_第25张图片

第4参数标识图片的透明度,在0-1之间

 

今天好像说的有点跑题,我们大概知道了new Scalar()里面参数的含义

并且知道了创建矩阵,通道,初始化赋值

通过上面的例子,希望你对mat有更多的理解,如果有什么不对还请多多指教

希望对你有所帮助

 

你可能感兴趣的:(opencv,opencv,java)