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

对初学者来说,我们总是希望通过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<Range>& 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有更多的理解,如果有什么不对还请多多指教

希望对你有所帮助

 

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
您可以使用 OpenCV 的 `Java2DFrameConverter` 和 `BufferedImageToMat` 来实现 `Mat` 转 `BufferedImage` 和 `BufferedImage` 转 `Mat` 的转换。 下面是将 `Mat` 转换为 `BufferedImage` 的示例代码: ```java import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.CvType; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; import org.opencv.videoio.VideoCapture; import org.opencv.videoio.Videoio; import org.opencv.imgcodecs.Imgcodecs; import java.awt.image.BufferedImage; import javax.swing.*; import org.bytedeco.javacv.Java2DFrameConverter; public class MatToBufferedImageExample { public static void main(String[] args) { // 加载OpenCV本地库 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); // 加载图像到Mat对象 Mat mat = Imgcodecs.imread("path/to/image.jpg"); // 创建Java2DFrameConverter对象 Java2DFrameConverter converter = new Java2DFrameConverter(); // 转换Mat为BufferedImage对象 BufferedImage image = converter.convertToBufferedImage(mat); // 显示图像 JFrame frame = new JFrame("Image"); frame.getContentPane().add(new JLabel(new ImageIcon(image))); frame.pack(); frame.setVisible(true); } } ``` 下面是将 `BufferedImage` 转换为 `Mat` 的示例代码: ```java import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.CvType; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; import org.opencv.videoio.VideoCapture; import org.opencv.videoio.Videoio; import org.opencv.imgcodecs.Imgcodecs; import java.awt.image.BufferedImage; import javax.swing.*; import org.bytedeco.javacv.BufferedImageToMat; public class BufferedImageToMatExample { public static void main(String[] args) { // 加载OpenCV本地库 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); // 加载图像到BufferedImage对象 BufferedImage image = ImageIO.read(new File("path/to/image.jpg")); // 创建BufferedImageToMat对象 BufferedImageToMat converter = new BufferedImageToMat(); // 转换BufferedImage为Mat对象 Mat mat = converter.convert(image); // 显示图像 Imgcodecs.imwrite("path/to/output_image.jpg", mat); } } ``` 这些示例代码需要使用到 OpenCVJavaCV 的库,请确保您已经成功安装了这些库。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值