使用JavaFX显示OpenCV Mat

7
我希望您能够直接使用JavaFX显示OpenCV中的Mat对象。我了解到可以将Mat对象转换为BufferedImage,但据我所知,无法使用JavaFX显示BufferedImage,因此需要进行另一种转换。
是否有一种方法可以直接将其转换为可由JavaFX显示的数据结构?

可能可以直接使用WritableImage转换为FX。可以通过将像素从Mat复制到WritableImagePixelWriter,或者通过实现由Mat支持的PixelReader,并直接使用它来实例化WritableImage来完成。 - Harald K
4个回答

7
我已经找到一种直接将Mat对象转换为JavaFX Image对象的方法。
MatOfByte byteMat = new MatOfByte();
Highgui.imencode(".bmp", mat, byteMat);
return new Image(new ByteArrayInputStream(byteMat.toArray()));

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


为什么我的OpenCV没有HighGUI库/类? - Zeta.Investigator

4

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。 - Roland
谢谢您的准确性,我刚刚编辑并纠正了我的答案。 - deb0ch

2

这个方法有点傻,首先需要将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);

我还没有测试这段代码,但这是一般的想法。


1

不需要编码和解码以获取所需的字节数组,您可以声明一个数组并使用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,大小对应于一个h乘以w和3个通道的图像。然后将数据从mat对象复制到数组中,并传递给PixelWriter对象pwsetPixels方法。

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