Проблема Понимание OpenCV Преобразование Mat в BufferedImage - PullRequest
0 голосов
/ 03 марта 2019

Я новый пользователь JAVA OpenCV, и сегодня я только изучаю официальное руководство о том, как преобразовать объект Mat в BufferedImage.

Из демонстрационного кода я могу понятьчто источником входного изображения является матричная форма, а затем sourcePixels представляется массивом байтов представления изображения, поэтому нам нужно получить значения из матрицы original в sourcePixels.Здесь sourcePixels имеет длину всей длины байтов изображения (с размером: w * h * каналов), поэтому он будет принимать значения всех байтов изображения сразу.

Тогда приходит то, что неинтуитивно понятен для меня.System.arraycopy(), кажется, копирует значения из sourcePixels в targetPixels, но на самом деле возвращает image.Из кода я могу догадаться, что targetPixels имеет отношение к image, но я не вижу, как мы копируем значения из 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;
}

1 Ответ

0 голосов
/ 03 марта 2019

Каждый BufferedImage поддерживается байтовым массивом, как и класс Mat из OpenCV, вызов ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); возвращает этот базовый байтовый массив и присваивает его targetPixels, другими словами, targetPixels балловв этот базовый байтовый массив, который BufferedImage image в настоящее время окружает, поэтому, когда вы вызываете System.arraycopy, вы фактически копируете из исходного байтового массива в байтовый массив BufferedImage, поэтому imageвозвращается, потому что в этот момент базовый байтовый массив, который инкапсулирует image, содержит данные пикселей из original, это похоже на этот небольшой пример, где после создания b указывает на, модификации 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);
...