捕获实时video设备中的图像以供基于Java的应用程序使用的最佳方法是什么?

我正在研究一个image processing问题,用于某些场景的半实时检测。 我的目标是以某种方式将实时video作为Motion JPEG帧存入Java代码中。

我对Java媒体框架非常熟悉,不幸的是,我认为我们可以认为这是一个有效的API。 我对Axis盒子也很熟悉,虽然我真的很喜欢他们的解决scheme,但是我希望对我的具体问题有任何批评意见。

这就是我为这个讨论的目的而定义“最佳”的方式:

  • 延迟 – 如果我使用这个videostream来控制摄像机,如果可能的话,我想保持我的往返延迟小于100毫秒。 这是从我的控制input到看到可见变化的时间之间的时间。 一段时间后编辑:另一个要记住的是,相机控制可能是手动和自动(事件触发器)的组合。 我们需要立即看到这些图片,即使高品质的饲料是分开存档。
  • 免费/开源比不免费更好。
  • 可调编解码器参数 – 我需要能够调整编解码器的某些情况。 有时高速低分辨率stream实际上更容易处理。
  • 与Java“集成” – 将这个解决scheme绑定到我的代码有多麻烦? 我是否通过套接字发送数据包? 打url? 安装Direct3D / JNI组合?
  • Windows / Linux /两者? – 我更喜欢操作系统不可知的解决scheme,因为我必须交付给几种风格的操作系统,但可能有一个解决scheme是最佳的一个,而不是其他。

注:我知道其他图像/video采集编解码器,这不是这个问题的重点。 由于帧精度的损失,我特别对stream媒体API(例如,MPEG4) 感兴趣。 但是,如果我的问题的解决scheme提供了另一个帧精确的数据stream,请join。

对这个问题的后续处理:在这一点上,我强烈倾向于购买安讯士video编码器等设备,而不是直接在软件或PC上采集video。 但是,如果有人有替代品,我很乐意听到他们的声音。

这个JavaCV实现工作正常。

码:

import com.googlecode.javacv.OpenCVFrameGrabber; import com.googlecode.javacv.cpp.opencv_core.IplImage; import static com.googlecode.javacv.cpp.opencv_highgui.*; public class CaptureImage { private static void captureFrame() { // 0-default camera, 1 - next...so on final OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0); try { grabber.start(); IplImage img = grabber.grab(); if (img != null) { cvSaveImage("capture.jpg", img); } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { captureFrame(); } } 

另外还有一个观看来自Camera的实况video 。 和JavaCV的configuration:

我认为这将符合你的要求。

FMJ绝对可以捕获video并将其转换为MJPEG帧。

关于JMF的死亡,你知道FMJ的执行吗? 我不知道它是否符合“最好”的解决scheme,但可能值得join讨论。

你有没有看过Processing.org ? 它基本上是一个简化的应用程序框架,用于开发“艺术”应用程序和物理计算平台,但是它基于Java,可以深入到“真实”的Java下面。

之所以想到的是,有几个video库的处理基本上是Java组件(至less我认为它们是 – 该网站有你可能需要的所有技术信息)。 在Eclipse IDE中有一个关于使用Processing库和工具的教程 。 video捕捉和处理也有很多例子 。

即使你不能直接使用这些库,Processing也是一个很好的语言/编程algorithm的环境。 有几个伟大的图像和video捕捉和实时处理的例子。

这是我的JavaCV实现高分辨率的video输出,并没有比其他解决scheme的帧速率明显下降(只有当我的networking摄像头重新聚焦,我注意到略有下降,但只有片刻)。

 import java.awt.image.BufferedImage; import java.io.File; import javax.swing.JFrame; import com.googlecode.javacv.CanvasFrame; import com.googlecode.javacv.OpenCVFrameGrabber; import com.googlecode.javacv.OpenCVFrameRecorder; import com.googlecode.javacv.cpp.opencv_core.IplImage; public class Webcam implements Runnable { IplImage image; static CanvasFrame frame = new CanvasFrame("Web Cam"); public static boolean running = false; public Webcam() { frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } @Override public void run() { try { grabber.setImageWidth(800); grabber.setImageHeight(600); grabber.start(); while (running) { IplImage cvimg = grabber.grab(); BufferedImage image; if (cvimg != null) { // opencv_core.cvFlip(cvimg, cvimg, 1); // mirror // show image on window image = cvimg.getBufferedImage(); frame.showImage(image); } } grabber.stop(); frame.dispose(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String... args) { Webcam webcam = new Webcam(); webcam.start(); } public void start() { new Thread(this).start(); running = true; } public void stop() { running = false; } } 

下面显示了一个使用Marvin框架的非常简单的实现。 使用Marvin,您可以轻松添加实时video处理。

 import javax.swing.JFrame; import marvin.gui.MarvinImagePanel; import marvin.image.MarvinImage; import marvin.video.MarvinJavaCVAdapter; import marvin.video.MarvinVideoInterface; public class SimpleVideoTest extends JFrame implements Runnable{ private MarvinVideoInterface videoAdapter; private MarvinImage image; private MarvinImagePanel videoPanel; public SimpleVideoTest(){ super("Simple Video Test"); // Create the VideoAdapter and connect to the camera videoAdapter = new MarvinJavaCVAdapter(); videoAdapter.connect(0); // Create VideoPanel videoPanel = new MarvinImagePanel(); add(videoPanel); // Start the thread for requesting the video frames new Thread(this).start(); setSize(800,600); setVisible(true); } public static void main(String[] args) { SimpleVideoTest t = new SimpleVideoTest(); t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } @Override public void run() { while(true){ // Request a video frame and set into the VideoPanel image = videoAdapter.getFrame(); videoPanel.setImage(image); } } } 

应用多种algorithm进行实时video处理的另一个例子 。