将OpenCV Mat对象转换为BufferedImage
我正在尝试使用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;
当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);
在上面的代码中,outputImage为NULL
有人有任何建议或想法吗?
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);
这样做,可以节省一个大字节数组分配和一个字节数组副本作为奖励。 🙂
我使用这种代码将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; }