将OpenCV Mat对象转换为BufferedImage

Joh*_* Ng 7 java opencv bufferedimage image

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

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;
Run Code Online (Sandbox Code Playgroud)

return_buff返回并转换为BufferedImage时,我得到NULL.当我注释掉该Imgproc.cvtColor函数时,它return_buff被正确转换为我可以显示的BufferedImage.好像Imgproc.cvtColor是返回一个我无法在Java中显示的Mat对象.

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

InputStream in = new ByteArrayInputStream(inputByteArray);
BufferedImage outputImage = ImageIO.read(in);
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,outputImage为NULL

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

har*_*ldK 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);
Run Code Online (Sandbox Code Playgroud)

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


小智 6

我使用这种代码将Mat对象转换为Buffered Image。

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;
}
Run Code Online (Sandbox Code Playgroud)