25

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

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

出于本次讨论的目的,这就是我定义“最佳”的方式:

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

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

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

4

6 回答 6

7

这个 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();
    }
}

还有关于从相机查看实时视频的帖子。以及 JavaCV 的配置:

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

于 2012-01-28T15:24:12.230 回答
3

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

于 2008-12-31T20:31:24.180 回答
2

关于 JMF 的死亡,你知道FMJ 的实现吗?我不知道它是否有资格作为“最佳”解决方案,但它可能值得加入讨论。

于 2008-09-30T17:32:35.937 回答
1

下面显示了一个使用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);
        }
    }
}

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

于 2013-07-24T16:16:02.380 回答
0

这是我的 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;
    }
}
于 2013-04-12T23:30:22.867 回答
-1

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

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

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

于 2008-09-22T20:28:24.173 回答