JavaCV Создать коврик из ресурса (InputStream)

Я использую JavaCV (не OpenCV). Моя цель — получить объект Mat из изображения, которое хранится как ресурс. Затем я передам этот метод Mat в метод opencv_imgproc.matchTemplate. Мне удалось написать этот плохой код:

    InputStream in = getClass().getResourceAsStream("Lenna32.png");
    BufferedImage image = ImageIO.read(in);
    Frame f = new Java2DFrameConverter().getFrame(image);
    Mat mat = new OpenCVFrameConverter.ToMat().convert(f);

Это работает в некоторых случаях. Проблемы:

  1. Для изображений png с каналом прозрачности (то есть 32BPP) он смещает каналы, так что R=00 G=33 B=66 A=FF превращается в R=33 G=66 B=FF Сдвиг цвета Lenna 32BPP

  2. В моей целевой среде я не могу использовать ImageIO

  3. Слишком много преобразований объектов InputStream -> BufferedImage -> Frame -> Mat. Я чувствую, что должен быть простой и эффективный способ сделать это.

Как лучше всего создать мат из ресурса?


person al0    schedule 30.10.2015    source источник


Ответы (1)


Я решил это, прочитав байты из InputStream и передав их в функцию imdecode:

InputStream is = context.getResourceAsStream("Lenna32.png");
int nRead;
byte[] data = new byte[16 * 1024];
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
while ((nRead = is.read(data, 0, data.length)) != -1) {
    buffer.write(data, 0, nRead);
}
byte[] bytes = buffer.toByteArray();
Mat mat = imdecode(new Mat(bytes), CV_LOAD_IMAGE_UNCHANGED);
person al0    schedule 03.11.2015
comment
Если вы можете использовать Apache Commons IO, вы можете преобразовать входной поток непосредственно в массив байтов с помощью одной строки с помощью IOUtils.toByteArray(is); - person Semaphor; 20.12.2018
comment
... или просто используйте встроенную функцию расширения inputStream.readAllBytes() в kotlin - person ruX; 21.02.2021