JavaCV Создать Mat из ресурса (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, имеющих канал прозрачности (то есть 32 бита на дюйм), он смещает каналы, так что R=00 G=33 B=66 A=FF превращается в R=33 G=66 B=FF Lenna 32BPP цветовой сдвиг

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

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

Каков наилучший способ создания мата из ресурса?

2 ответа

Решение

Я решил это путем чтения байтов из 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);

Для справки: чтобы преобразовать InputStream в Mat, @Kotlin:

      val bytes = inputStream.readBytes()
val mat = Mat(1, bytes.size, CvType.CV_8UC1)
mat.put(0, 0, bytes)
return Imgcodecs.imdecode(mat, Imgcodecs.IMREAD_UNCHANGED)
Другие вопросы по тегам