Opencv 使用JavaCV显示摄像机的实时图像

Opencv 使用JavaCV显示摄像机的实时图像,opencv,live,javacv,Opencv,Live,Javacv,我正在使用JavaCV进行网络摄像头的实时图像处理。它工作得很好!我可以在图片中定义一个感兴趣的区域,并在显示之前对每个图像进行裁剪,它仍然可以每秒进行整整30帧的处理,没有任何问题。很好 但是,我正在使用CanvasFrame对象来显示实时图像。它工作得很好(也很简单),但对于包含在应用程序中来说是完全无用的。我想把实时图像作为我的应用程序窗口的一个元素放在面板(或画布或任何东西)上 问题是:画布框架存在于自己的框架中,当我的窗口获得焦点时,画布框架消失在我的窗口后面,当我移动窗口时,画布框架

我正在使用JavaCV进行网络摄像头的实时图像处理。它工作得很好!我可以在图片中定义一个感兴趣的区域,并在显示之前对每个图像进行裁剪,它仍然可以每秒进行整整30帧的处理,没有任何问题。很好

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

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

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


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

我启动一个摄像头线程,它在画布框上画一个圈,直到按下一个UI按钮。这个很好用

为了响应UI按钮的按下,我停止线程(触发grabber.stop)。然后我拍摄最后一张图像,并将其显示在面板上。这很好(我知道如何显示图像,谢谢)。我会做的,除了画布框架是一个单独的窗口,有点吸

因此,我想开始一个摄像头线程,它在一个循环中抓取,而不是在画布框架上绘制。相反,它只保留最后一个图像的内部副本。然后,为了在我的UI上显示,我设置了一个计时器(可以正确启动)并在面板上显示最新的图像。这不起作用--面板仍为空。然而,这种情况与实际情况有什么不同?唯一的区别是摄像头线程中的抓取器尚未停止。当相机不在抓取循环中时可以,但在循环时不会显示。我很小心地将我传递到UI的图像复制成cvCopy,所以内存争用没有问题

我还要说,在画布框上以循环方式显示似乎会触发我的Logitech C920自动对焦,而仅仅抓取一张图像并显示它(只要抓取器停止,我就可以轻松完成)似乎不会自动对焦

结果是,CanvasFrame似乎在背景音乐中做了很多棘手的事情,而这是不可能仅仅通过grabber.start、grabber.grab、grabber.stop,然后在您自己的面板上显示来匹配的


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

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

然后,我在主事件线程中设置了一个计时器,使其每秒唤醒20到30次(30-50毫秒),在报警回调方法中,我只需调用mypanel.setImage(latestPhoto);这就像是一个活生生的图像

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


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

进一步测试。因为CanvasFrame对象提供了一个getCanvas()方法,所以我尝试使用它,然后将收到的画布放入我的UI中。然而,这并不奏效。框架仍然作为一个单独的窗口弹出,其画布在其中(并且工作),UI上的画布保持空白。所以这并不能解决我的问题。有什么想法吗?进一步测试。由于CanvasFrame对象提供add()方法,我尝试将一些UI元素移动到其中(而不是相反)。这起作用了,即使run()方法继续运行,事件仍在处理中。但是,我不能在画布框架上设置未装饰(我想这样做)。我现在确信,我将解决这个问题的方法是从画布框架的源代码开始,修改它,使其可以被取消装饰,以及您需要修改的任何其他内容(我已成功完成),然后制作一个修改后的画布框架,并将其用作整个UI的容器(类似于创建容器面板的方式)。我将报告我的结果。了解并为你从相机获得的每一张图像做这件事!好的,我看到我错误地注释掉了重绘。即使抓取器在另一个线程中启动(但未停止),我也可以很好地绘制图像因此,您可以在自己的UI元素上绘制它,就像CanvasFrame自己绘制一样。谢谢Sam,你在库中的出色工作很好——我对每一帧都进行了非常复杂的处理,并且仍然可以比相机提供的速度更快:30+fps。有时我实际上会处理同一帧两次,因为摄影机线程跟不上JavaCV代码!美好的再次感谢。哦,罗技C920中的自动对焦功能不管显示的是什么元素都能正常工作,所以它工作得很好,因为硬件/驱动程序组合甚至在移交图像之前就已经处理好了。这并不是世界上最好的自动对焦,但是任何AF都会有困难——使用更多的光线会有帮助。不管怎样,如果
CanvasFrame
显示出你想要的效果,你有没有尝试过在你想要使用的
Frame
中做类似的事情?注意,主线程可以自己做grabber.grab(),而不是使用单独的线程。请记住,grab()是一种阻塞读取,这对于某些系统可能是一个问题。如果使用依赖于后续帧之间差异的算法,则使用单独的线程将不起作用,因为如果不同步,您捕获的两个帧实际上可能是来自摄影机的单个帧。
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();
    }
}