1

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

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

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

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

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

4

2 回答 2

0

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

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

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

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

结果是 CanvasFrame 似乎在背景中做了很多棘手的事情,这些事情无法通过仅使用grabber.start、grabber.grab、grabber.stop 来匹配,然后显示在您自己的面板上。

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

于 2013-01-04T16:47:14.747 回答
0

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

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 毫秒),在闹钟回调方法中,我只需调用 mypanel.setImage(latestPhoto); 它就像一个实时图像。

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

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

于 2013-01-11T17:51:01.330 回答