理解 OpenCV 的问题将 Mat 转换为 BufferedImage

Problem Understanding OpenCV Convert Mat to BufferedImage

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

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

然后就出现了这个,这对我来说并不直观。 System.arraycopy() 似乎将值从 sourcePixels 复制到 targetPixels,但实际上 returns 是 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;
}

每个 BufferedImage 都由一个字节数组支持,就像来自 OpenCV 的 Mat class 一样,调用 ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); returns 这个底层字节数组并将其分配给 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);