2014-11-23 4 views
5

Я пытаюсь создать вспомогательную функцию с использованием Java API OpenCV, которая обрабатывает входное изображение и возвращает выходной массив байтов. Входное изображение представляет собой файл jpg, сохраненный на компьютере. Изображение ввода и вывода отображается в пользовательском интерфейсе Java с помощью Swing.Преобразование объекта OpenCV Mat в BufferedImage

System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 
// Load image from file 
Mat rgba = Highgui.imread(filePath); 

Imgproc.cvtColor(rgba, rgba, Imgproc.COLOR_RGB2GRAY, 0); 

// Convert back to byte[] and return 
byte[] return_buff = new byte[(int) (rgba.total() * rgba.channels())]; 
rgba.get(0, 0, return_buff); 
return return_buff; 

Когда return_buff возвращается и преобразуется в BufferedImage я получаю NULL обратно. Когда я комментирую функцию Imgproc.cvtColor, return_buff правильно преобразован в BufferedImage, который я могу отобразить. Кажется, что Imgproc.cvtColor возвращает объект Mat, который я не мог отобразить на Java.

Вот мой код для преобразования байт [], чтобы BufferedImage:

InputStream in = new ByteArrayInputStream(inputByteArray); 
BufferedImage outputImage = ImageIO.read(in); 

В коде выше, outputImage является NULL

Кто-нибудь есть какие-либо предложения или идеи?

ответ

10

ImageIO.read(...) (и пакет javax.imageio) предназначен для чтения/записи изображений из форматов файлов. У вас есть массив, содержащий «сырые» пиксели. Для ImageIO невозможно определить формат файла из этого массива байтов. Из-за этого он вернется null.

Вместо этого вы должны создать BufferedImage из байтов напрямую. Я не знаю OpenCV, но я предполагаю, что результатом Imgproc.cvtColor(rgba, rgba, Imgproc.COLOR_RGB2GRAY, 0) будет изображение в оттенках серого (8 бит/образец, 1 образец/пиксель). Это тот же формат, что и BufferedImage.TYPE_BYTE_GRAY. Если это предположение верно, то вы должны быть в состоянии сделать:

// Read image as before 
Mat rgba = Highgui.imread(filePath); 
Imgproc.cvtColor(rgba, rgba, Imgproc.COLOR_RGB2GRAY, 0); 

// Create an empty image in matching format 
BufferedImage gray = new BufferedImage(rgba.width(), rgba.height(), BufferedImage.TYPE_BYTE_GRAY); 

// Get the BufferedImage's backing array and copy the pixels directly into it 
byte[] data = ((DataBufferByte) gray.getRaster().getDataBuffer()).getData(); 
rgba.get(0, 0, data); 

делая это таким образом, экономит вам одно большое выделение байтового массива и один экземпляр байтового массива в качестве бонуса. :-)

2

Я использовал этот код для преобразования объекта Mat в буферное изображение.

static BufferedImage Mat2BufferedImage(Mat matrix)throws Exception {   
    MatOfByte mob=new MatOfByte(); 
    Imgcodecs.imencode(".jpg", matrix, mob); 
    byte ba[]=mob.toArray(); 

    BufferedImage bi=ImageIO.read(new ByteArrayInputStream(ba)); 
    return bi; 
} 
Смежные вопросы