将OpenCV Mat对象转换为BufferedImage [英] Convert OpenCV Mat object to 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屋!