将OpenCV Mat对象转换为BufferedImage

9
我正在尝试使用 OpenCV Java API 创建一个辅助函数,该函数可以处理输入图像并返回输出字节数组。输入图像是计算机中保存的 jpg 文件。在 Java UI 中使用 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返回了一个Mat对象,而这在Java中无法显示。
以下是我的代码,将byte[]转换为BufferedImage:
InputStream in = new ByteArrayInputStream(inputByteArray);
BufferedImage outputImage = ImageIO.read(in);

在上面的代码中,outputImage是空的。
有人有任何建议或想法吗?
2个回答

11

ImageIO.read(...)(以及整个javax.imageio包)用于从/向文件格式读取/写入图像。您拥有的是包含“原始”像素的数组。因此,ImageIO无法从这个字节数组中确定文件格式。因此,它将返回null

相反地,您应该直接从字节创建一个BufferedImage。我不太了解OpenCV,但我假设Imgproc.cvtColor(rgba, rgba, Imgproc.COLOR_RGB2GRAY, 0)的结果将是灰度图像(每个样本8位,每个像素1个样本)。这与BufferedImage.TYPE_BYTE_GRAY相同。如果这个假设是正确的,您应该能够执行以下操作:

// Read image to Mat as before
Mat rgba = ...;
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);

采用这种方式,还可以额外节省一个大的字节数组分配和一个字节数组拷贝。 :-)


这个答案已经过时了。自3.0版本以后,openCV中不再有Highgui模块。来源:https://dev59.com/6V8f5IYBdhLWcg3wFfP_ - Prometheus
1
@Prometheus 更新了答案。问题是关于从Mat转换为BufferedImage,而不是关于如何使用OpenCV读取图像,因此我只是删除了对HighGUI的引用。 - Harald K

9

我使用了这段代码将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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接