将OpenCV Mat对象转换为BufferedImage [英] Convert OpenCV Mat object to BufferedImage

查看:252
本文介绍了将OpenCV Mat对象转换为BufferedImage的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用OpenCV Java API创建一个辅助函数,该函数将处理输入图像并返回输出字节数组。输入图像是保存在计算机中的jpg文件。输入和输出图像使用Swing显示在Java UI中。

I am trying to create a helper function using OpenCV Java API that would process an input image and return the output byte array. The input image is a jpg file saved in the computer. The input and output image are displayed in the Java UI using Swing.

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 正在返回一个我无法用Java显示的Mat对象。

When the return_buff is returned and converted to BufferedImage I get NULL back. When I comment out the Imgproc.cvtColor function, the return_buff is properly converted to a BufferedImage that I can display. It seems like the Imgproc.cvtColor is returning a Mat object that I couldn't display in Java.

这里是我的代码从byte []转换为BufferedImage:

Here's my code to convert from byte[] to BufferedImage:

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

在上面的代码中,outputImage为NULL

In above code, outputImage is NULL

有人有任何建议或想法吗?

Does anybody have any suggestions or ideas?

推荐答案

ImageIO.read(...)(以及一般的 javax.imageio 包)用于从/向文件格式读取/写入图像。你有一个包含原始像素的数组。 ImageIO 不可能从此字节数组中确定文件格式。因此,它将返回 null

ImageIO.read(...) (and the javax.imageio package in general) is for reading/writing images from/to file formats. What you have is an array containing "raw" pixels. It's impossible for ImageIO to determine file format from this byte array. Because of this, it will return null.

相反,你应该创建一个 BufferedImage 直接来自字节。我不太了解OpenCV,但我假设 Imgproc.cvtColor(rgba,rgba,Imgproc.COLOR_RGB2GRAY,0)的结果将是一个图像灰度(8位/样本,1个样本/像素)。这与 BufferedImage的格式相同。 TYPE_BYTE_GRAY 。如果这个假设是正确的,你应该可以这样做:

Instead, you should create a BufferedImage from the bytes directly. I don't know OpenCV that well, but I'm assuming that the result of Imgproc.cvtColor(rgba, rgba, Imgproc.COLOR_RGB2GRAY, 0) will be an image in grayscale (8 bits/sample, 1 sample/pixel). This is the same format as BufferedImage.TYPE_BYTE_GRAY. If this assumption is correct, you should be able to do:

// 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);

这样做,可以节省一个大字节数组分配和一个字节数组副本作为奖励。 : - )

Doing it this way, saves you one large byte array allocation and one byte array copy as a bonus. :-)

这篇关于将OpenCV Mat对象转换为BufferedImage的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆