使用JavaCV显示来自摄像头的实时图像

时间:2012-12-24 20:15:52

标签: opencv live javacv

我正在使用JavaCV从网络摄像头进行即时图像处理。它很棒!我可以在图片中定义一个感兴趣的区域并在显示之前裁剪每个图像,并且它仍然可以每秒完整地生成30帧而没有问题。尼斯!

但是,我正在使用CanvasFrame对象来显示实时图像。它工作得很好(而且很简单),但是在应用程序中包含它是完全无用的。我想将实时图像作为应用程序窗口的一个元素放在面板(或画布或其他)上。

问题:CanvasFrame存在于自己的框架中,当我的窗口获得焦点时,它会在窗口后面消失,而当我移动窗口时也不会移动。

如何将实时图像放到我可以与普通UI元素集成的元素上?

同样,我需要在JavaCV中替换CanvasFrame。 TIA。

2 个答案:

答案 0 :(得分:0)

我启动了一个相机线程,它在循环中抓取并在CanvasFrame上绘制,直到按下UI按钮。这个工作很精细。

响应按下UI按钮,我停止线程(触发grabber.stop)。然后我拍摄最后一张图像,并在面板上显示该图像。这个工作很精细(我知道如何显示图像,谢谢)。我会完成的,除了CanvasFrame是一个单独的窗口,有点糟糕。

所以我想开始一个抓住循环并且不在CanvasFrame上绘制的相机线程。相反,它只保留最后一张图像的内部副本。然后,为了在我的UI上显示,我设置了一个计时器(正确触发),并在我的面板上显示最新的图像。这不起作用 - 面板保持空白。然而,这个案例与有效的案例有什么不同?唯一的区别是相机线程中的抓取器尚未停止。当相机不在其抓取环中时它很好,但在循环时不会显示。我小心翼翼地制作了传递给用户界面的图像的cvCopy,因此争用内存没有问题。

我还会说在循环中在CanvasFrame上显示似乎会触发我的Logitech C920自动对焦,而只是抓取单个图像并显示它(只要抓取器停止,我就可以轻松完成)不会似乎是自动对焦。

结果是CanvasFrame似乎在backgraound中做了很多棘手的事情,只有抓住grabber.start,grabber.grab,grabber.stop才能匹配,然后显示在你自己的面板上。

Sam,我在CanvasFrame源代码中看到了你的名字,所以你应该比任何人都更清楚我的两个场景之间的区别。

答案 1 :(得分:0)

我一直在寻找CanvasFrame的替代品,可以在任何UI中使用,现在我有一个。这是一个可以显示实时(或静止)图像的swing元素:

import java.awt.Graphics;
import java.awt.image.*;

import javax.swing.JPanel;

public class CamImagePanel extends JPanel {

    private BufferedImage image;

    public CamImagePanel() {
        super();
        // Note that at this point, image = null
        // so be sure to call setImage() before setVisible(true)
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (image != null)      // Not efficient, but safer.
            g.drawImage(image, 0, 0, this);
    }

    public void setImage(BufferedImage img) {
        image = img;
        repaint();
    }
}

然后,我在主事件线程中设置一个定时器,每秒唤醒20到30次(30-50 ms),在报警回调方法中,我只需调用mypanel.setImage(latestPhoto);它就像一个实时图像。

我有一个控制器对象,它有自己的线程,尽可能快地用相机中的图像填充缓冲区,我只是向控制器询问最新的图像。这样,不需要同步,我实际上可以要求比相机更快或更慢的图像,我的逻辑仍然可以正常工作。

UI上的一个按钮会停止计时器,我可以在面板上保留最终图像,或者使用setVisible(false)将面板完全取下。