IplImage/Mat в байтовый массив и обратно с JavaCV 1.2

Кажется, слишком много раз "уже ответили" на тему, но тем не менее я не смог найти работоспособного решения. Мне нужно сериализовать IplImages и Mats с помощью JavaCV. Я не могу использовать файловую систему, и я должен придерживаться JavaCV 1.2/JavaCPP 1.2.4/OpenCV 3.1 (примечание: я не могу использовать собственную оболочку Java OpenCV - мне нужно работать с JavaCV). Я нашел ряд рекомендаций на Stackoverflow, но все они либо: 1) используют устаревший метод, либо 2) используют методы, которых больше не существует. Я знаю, что IplImages и Mats легко взаимозаменяемы, поэтому решение для одного будет легко применимо для другого. Идеальным решением был бы способ конвертировать IplImage/Mat в байтовый массив и обратно. Я надеюсь, что вы, ребята, можете помочь.


person lcofresi    schedule 22.10.2016    source источник


Ответы (1)


У меня есть решение для самой последней версии JavaCV. Вернее, несколько. У меня были проблемы с некоторыми изображениями, поэтому моя вторая попытка преобразования в массив байтов дала более стабильный результат. Решения здесь на Scala.

Чтобы преобразовать в массив байтов данные изображения, вам нужно получить байты.

Mat m = new Mat(iplImage);
ByteBuffer buffer = this.image.asByteBuffer();
Mat m = new Mat(this.image);
int sz = (m.total() * m.channels());
byte[] barr = new byte[sz]();
m.data().get(barr);

Преобразуйте в java.nio.ByteBuffer, используйте общий размер вашего изображения (я преобразовал в мат) и получите данные. Я забыл, возвращает ли m.total * m.channels значение double, long, int или float. Я использовал .toInt в Scala.

Другой вариант — использовать BufferedImage. Некоторые из моих изображений получались немного странными, используя только JavaCV.

BufferedImage im = new Java2DFrameConverter().convert(new OpenCVFrameConverter.ToIplImage().convert(this.image))
BytearrayOutputstream baos = new ByteArrayOutputStream();
byte[] barr = null;
try{
    ImageIO.write(im,"jpg",baos);
    baos.flush();
    barr = baos.toByteArray();
}finally{
    baos.close();
}
//This could be try with resources but the original was in Scala.

Чтобы преобразовать массив байтов в IplImage, я фактически использую буферизованное изображение для надежности.

ImplImage im = null;
InputStream in = new ByteArrayInputStream(bytes);
try {
    Mat m = new Mat(image.getHeight,image.getWidth,image.getType,new BytePointer(ByteBuffer.wrap(image.getRaster.getDataBuffer.asInstanceOf[DataBufferByte].getData)));
    im = new IplImage(m);
}finally{
    in.close();
}
//Again this could be try with resources but the original example was in Scala
person Andrew Scott Evans    schedule 17.02.2017
comment
Это именно то, что я искал, за исключением того, что я совершенно неграмотен в Scala. Кто-нибудь потрудился бы перекодировать это на Java? - person lcofresi; 26.03.2017
comment
Дай мне минуту. Их будет 2. Это взято из моего репозитория github.com/SimplrTek/GoatImaging2. - person Andrew Scott Evans; 27.03.2017
comment
@Icofresi Преобразование довольно простое. Я оставил для вас несколько заметок. В примерах JavaCV используется Scala, поскольку он может взаимодействовать с библиотеками Java при компиляции байтового кода JVM. - person Andrew Scott Evans; 27.03.2017
comment
В моем блоге @Icofresi есть дополнительная информация о JavaCV с серией примеров dadruid5 .com/2017/02/15/java-cv-basics-iplimage - person Andrew Scott Evans; 27.03.2017
comment
Ваш блог превосходен. Большая помощь. Большое спасибо. Если вы позволите мне два вопроса: Считаете ли вы целесообразным перейти от оболочки JavaCV bytedeco к собственной OpenCV? Где можно найти двоичные файлы предварительной сборки для пакетов Contrib OpenCV (имеется в виду файлы jar и dll/so)? - person lcofresi; 01.04.2017
comment
@ИкоФреси. Извините за опоздание. Я был очень занят. Я использую JavaCV, потому что он обновлен и предварительно создан с поддержкой Maven. В этом блоге показано, как создать OpenCV3 с поддержкой Java с нуля. elbauldelprogramador.com/en/ - person Andrew Scott Evans; 09.06.2017