在OpenCV :: VideoCapture中引入延迟

时间:2013-05-04 22:30:27

标签: qt opencv

我有一个继承自cv :: VideoCapture的类Camera,其核心方法是将我从实时流中获取的cv :: Mat转换为QImage:

QImage Camera::getFrame() {
    if(isOpened()) {
        cv::Mat image;
        (*this) >> image;
        cv::cvtColor(image, image, CV_BGR2RGB);
        return QImage((uchar*) image.data, image.cols, image.rows, image.step, QImage::Format_RGB888);
    }
    else return QImage();
}

一个封装类CameraDelayedView,它调用此方法并添加延迟:

void CameraDelayedView::timerEvent(QTimerEvent *evt) {
    if(cam != NULL) {
        buffer.enqueue(cam->getFrame());

        if(buffer.size() > delay*fps) {
            setPixmap(QPixmap::fromImage(buffer.dequeue()));
        }
    }
}

我可以看到延迟5秒,视频的初始显示被延迟,但之后它会顺利运行。几乎看起来图像仍然以某种方式通过指针链接到实时馈送(或者QQeueue不是一个合适的FIFO,但我怀疑它)......是这样吗?

如果是这样,我可以通过这种方式回答其他正在经历相同事情的人,我会对一种有效的复制方式感兴趣(或者更有效的上述代码)。如果没有,我不知道发生了什么......

提前致谢。

此致 Mystère先生

2 个答案:

答案 0 :(得分:2)

摄像机的摄像头在某种缓冲区中排队。我自己一直在努力解决这个问题,使用一个单独的线程来解决它,它不断从缓冲区获取帧,如果被要求发送一个帧到主线程。

答案 1 :(得分:2)

STREAM-ON(在v4l术语中)请求后,所有摄像机都需要预热的时间,范围从几毫秒到几秒。

如果您无法承受第一帧的延迟,最好让相机保持开启状态。然后,您可能会发现自己变老了。在这种情况下,您需要在开头冲洗相机。那就是:在有这样的情况下,快速丢弃每个可用的[陈旧]帧。 (你需要能够知道是否有新图像没有阻塞)

另一种方法是让线程使用这些图像,并仅在需要时使用它们。