使用 JavaFX 显示 OpenCV Mat

Posted

技术标签:

【中文标题】使用 JavaFX 显示 OpenCV Mat【英文标题】:Display OpenCV Mat with JavaFX 【发布时间】:2015-03-01 13:16:20 【问题描述】:

我想直接使用 JavaFX 显示来自 OpenCV 的 Mat 对象。我已经看到可以将Mat 对象转换为BufferedImage。但据我所知,您无法使用 JavaFX 显示 BufferedImage,因此必须进行另一次转换。

有没有办法直接将其转换成JavaFX可以显示的数据结构?

【问题讨论】:

可以使用WritableImage 直接转换为FX。通过将像素从Mat 复制到WritableImagePixelWriter,或者通过实现由Mat 支持的PixelReader,并将其用于直接实例化WritableImage 【参考方案1】:

我找到了一种将Mat 对象转换为JavaFX Image 对象的直接方法。

MatOfByte byteMat = new MatOfByte();
Highgui.imencode(".bmp", mat, byteMat);
return new Image(new ByteArrayInputStream(byteMat.toArray()));

您也可以将其编码为 .jpg,但 .bmp 更快。

【讨论】:

为什么我的 OpenCV 没有附带 HighGUI 库/类?【参考方案2】:

TomTom 的回答非常有帮助,解决了问题,但是 Highgui 在 java 中不再有任何绑定。

从 OpenCV 3.0.0 开始,最新的代码更像:

MatOfByte byteMat = new MatOfByte();
Imgcodecs.imencode(".bmp", mat, byteMat);
return new Image(new ByteArrayInputStream(byteMat.toArray()));

【讨论】:

你的答案是 OpenCV 版本 3 的解决方案。早期版本使用 Highgui。 感谢您的精确,我刚刚编辑并更正了我的答案。【参考方案3】:

这样做的愚蠢方法是将Mat 转换为BufferedImage,然后将其转换为Image,以便它可以显示在ImageView 中:

Mat >> BufferedImage >> Image >> ImageView

假设您知道如何进行第一次转换,其余的将是这样的:

import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;

Image image = SwingFXUtils.toFXImage(bufImage, null);

ImageView imgView = new ImageView();
imgView.setImage(image);

我没有测试过代码,但这是大致的想法。

【讨论】:

【参考方案4】:

无需编码和解码来获得所需的字节数组,您只需声明一个数组并使用get 方法即可。这是 Scala 代码,但希望它易于理解:

val arr = new Array[Byte](w * h * 3)
mat.get(0, 0, arr)
pw.setPixels(0, 0, w, h, PixelFormat.getByteRgbInstance, arr, 0, w * 3)

此代码声明了byte[] 类型的数组arr,其大小对应于w 和3 个通道的h 图像。然后将数据从mat对象复制到数组中,并从PixelWriter对象pw传递给setPixels方法。

【讨论】:

以上是关于使用 JavaFX 显示 OpenCV Mat的主要内容,如果未能解决你的问题,请参考以下文章

无法同时显示五个 Mat 图像(C++、OpenCV)

将我的数组移动到 Mat 并使用 openCV 显示图像

如何在 MFC 视图上显示 OpenCV Mat

02OpenCV数据载入显示与保存

LIBTIFF 16位灰度tif图像转成OpenCV中的Mat格式并显示

OPENCV学习笔记2_Mat 加载, 显示