从实时视频设备捕获图像以供基于 Java 的应用程序使用的最佳方法是啥?

Posted

技术标签:

【中文标题】从实时视频设备捕获图像以供基于 Java 的应用程序使用的最佳方法是啥?【英文标题】:What is the best method to capture images from a live video device for use by a Java-based application?从实时视频设备捕获图像以供基于 Java 的应用程序使用的最佳方法是什么? 【发布时间】:2010-09-12 01:32:46 【问题描述】:

我正在研究用于半实时检测某些场景的图像处理问题。我的目标是让实时视频以我的 Java 代码中的 Motion JPEG 帧的形式出现在我的 Java 代码中不知何故

我对@9​​87654321@ 很熟悉,但遗憾的是,我认为我们可以认为这是一个有效死的 API。我也熟悉Axis boxes,虽然我真的很喜欢他们的解决方案,但如果我对我的特定兴趣点提出任何批评性反馈,我将不胜感激。

为了本次讨论的目的,这就是我对“最佳”的定义:

延迟 - 如果我使用此视频流控制摄像头,我希望尽可能将往返延迟保持在 100 毫秒以下。这是从我的控制输入到我看到可见变化之间的时间来衡量的。稍后编辑:要记住的另一件事是相机控制可能是手动和自动(事件触发器)的组合。我们需要立即查看这些图片,即使高质量的 Feed 是单独存档的。 免费/开源总比不免费好。 可调整的编解码器参数 - 我需要能够针对某些情况调整编解码器。有时,高速低分辨率流实际上更容易处理。 “集成”与 Java - 将此解决方案与我的代码挂钩有多麻烦?我是否通过套接字发送数据包?点击网址?安装 Direct3D/JNI 组合? Windows / Linux / 两者? - 我更喜欢与操作系统无关的解决方案,因为我必须提供多种操作系统,但可能有一种解决方案对其中一种而言是最佳的,而对另一种则不是。

注意:我知道其他图像/视频捕获编解码器,这不是这个问题的重点。由于帧精度的损失,我对流 API(例如 MPEG4)特别感兴趣。但是,如果我的问题有提供另一个帧精确数据流的解决方案,请加入。

跟进这个问题:在这一点上,我强烈倾向于购买诸如Axis video encoders 之类的设备,而不是尝试在软件中或直接在 PC 上捕获视频。但是,如果有人有其他选择,我很乐意听到。

【问题讨论】:

【参考方案1】:

这个 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的post on viewing live video和configuration for JavaCV :

我认为这将满足您的要求。

【讨论】:

有趣 - 有没有关于图像采集卡延迟的数据? 我没有计算或找到这样的数据。但看起来不错。在此视频youtube.com/watch?v=r02no-zIBnI 中,我在 JFrame 中显示捕获的图像 (IplImage img = grabber.grab())。【参考方案2】:

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

【讨论】:

【参考方案3】:

关于JMF的死亡,你知道FMJ implementation吗?我不知道它是否称得上是“最佳”解决方案,但它可能值得加入讨论。

【讨论】:

最后一次更新似乎是很久以前的事了:sourceforge.net/project/showfiles.php?group_id=161490 自 2007 年以来已经死掉的 API 可能对我们没有帮助。不过还是谢谢。【参考方案4】:

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

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);
        
    

另一个example 应用多种算法进行实时视频处理。

【讨论】:

这很有趣 - 你能谈谈我上面的延迟要求吗? 延迟取决于应用程序的硬件、摄像头和视频分辨率。不过,我认为这是可行的。看看这个实时视频处理demo。它展示了这个框架的实际效果。 marvinproject.org 链接已失效。你能更新一下吗?看起来你是那个不错的图书馆的作者,所以你可能想说:) @Matthieu 感谢您的报告。【参考方案5】:

这是我的 JavaCV 实现,具有高分辨率视频输出,与其他解决方案相比,帧速率没有明显下降(只有当我的网络摄像头重新聚焦时,我才注意到轻微下降,但只是片刻)。

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;
    

【讨论】:

【参考方案6】:

你看过Processing.org吗?它基本上是一个用于开发“艺术”应用程序和物理计算平台的简化应用程序框架,但它是基于 Java 的,您可以深入挖掘底层的“真正”Java。

想到的原因是有几个视频libraries 用于处理,它们基本上是 Java 组件(至少我认为它们是 - 该站点包含您可能需要的所有技术信息)。在 Eclipse IDE 中使用处理库和工具有一个tutorial。还有很多examples关于视频采集和处理的。

即使您不能直接使用这些库,Processing 也是一种用于制定算法的出色语言/环境。那里有几个很好的图像和视频捕获以及实时处理示例。

【讨论】:

以上是关于从实时视频设备捕获图像以供基于 Java 的应用程序使用的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在实时视频捕获应用程序中使用相机校准参数

从网络摄像机捕获实时图像

Python-视频

如何从 android 的视频视图中显示的 ip 摄像头的流式视频中捕获图像

基于WebRTC开源框架的实时视频聊天项目,搭建私人实时通信服务

视频捕获 + 上传 + 处理 + 流回 - .NET & C#