【问题标题】:Problem Understanding OpenCV Convert Mat to BufferedImage问题理解 OpenCV Convert Mat to BufferedImage
【发布时间】:2019-03-03 08:05:32
【问题描述】:

我是JAVA OpenCV的新用户,今天刚通过官方教程学习如何将Mat对象转换为BufferedImage

从demo代码中可以了解到输入的图片源是一个Matrix形式,然后sourcePixels好像会是图片的字节数组表示,所以我们需要从@987654324中获取值@矩阵到sourcePixels。这里sourcePixels 具有整个图像字节长度的长度(大小:w * h * 通道),因此它会一次获取整个图像字节值。

然后它来了,这对我来说并不直观。 System.arraycopy() 似乎将值从sourcePixels 复制到targetPixels,但实际返回的是image。我可以从代码中猜到targetPixelsimage 有关系,但是我看不到我们如何将值从sourcePixels 复制到targetPixels,但它实际上会影响image 的值?

这是演示代码。谢谢!

private static BufferedImage matToBufferedImage(Mat original)
{
    BufferedImage image = null;
    int width = original.width(), height = original.height(), channels = original.channels();
    byte[] sourcePixels = new byte[width * height * channels];

    original.get(0, 0, sourcePixels);

    if (original.channels() > 1)
    {
        image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
    }
    else
    {
        image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
    }

    final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
    System.arraycopy(sourcePixels, 0, targetPixels, 0, sourcePixels.length);

    return image;
}

【问题讨论】:

    标签: opencv bufferedimage


    【解决方案1】:

    每个BufferedImage 都由一个字节数组支持,就像OpenCV 中的Mat 类一样,对((DataBufferByte) image.getRaster().getDataBuffer()).getData(); 的调用返回这个底层字节数组并将其分配给targetPixels,换句话说,targetPixels 点到BufferedImage image 当前正在环绕的这个底层字节数组,所以当你调用System.arraycopy 时,你实际上是从源字节数组复制到BufferedImage 的字节数组中,这就是image 的原因正在返回,因为此时image封装的底层字节数组包含来自original的像素数据,就像这个小例子一样,在将b指向a之后,对b的修改也会反映在a中,就像tagetPixels一样,因为它指向字节数组image是封装的,从sourcePixels复制到targetPixels也会改变image

    int[] a = new int[1];
    int[] b = a;
    // Because b references the same array that a does
    // Modifying b will actually change the array a is pointing to
    b[0] = 1;
    System.out.println(a[0] == 1);
    

    【讨论】:

    • 感谢您提供清晰明了的解释!现在对我来说很有意义。我曾经认为 Java 没有办法获取引用的地址(如 C++ 中的指针变量),并且没有意识到“共享引用”,就像你的例子中的那样,在 Java 中仍然有效。那么在这种情况下,我可以将这一行((DataBufferByte) image.getRaster().getDataBuffer()).getData() 解释为获取image 引用的地址和大小吗?换句话说,它检索image 的地址并使数组targetPixels 指向与image 相同的地址?
    • @KatherineChen 你可以这么想,但准确地说,Java 不允许你像在 C/C++ 中那样直接使用指针,Java 使用 references 来抽象出指针的概念,但本质上,一个引用和一个指针代表一个内存块的句柄,只是每种语言允许你去的低级方式不同
    • 全部清除,谢谢!这听起来像是关于您可以如何精确地操纵对象地址的水平差异。直到!谢谢!
    猜你喜欢
    • 2022-11-05
    • 2017-02-19
    • 1970-01-01
    • 1970-01-01
    • 2015-01-21
    • 2017-12-15
    • 1970-01-01
    • 1970-01-01
    • 2013-08-27
    相关资源
    最近更新 更多