Mister Mystère
Mister Mystère

Reputation: 1012

Introducing a delay in OpenCV::VideoCapture

I have a class Camera inheriting from cv::VideoCapture, which its core method is to convert a cv::Mat that I get from a live stream to a 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();
}

And an encapsulating class CameraDelayedView which calls this method and adds a delay :

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

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

I can see with a delay of 5seconds that the initial display of the video is delayed, but after that it runs smoothly. It nearly seems like the images are still somehow linked to the live feed through pointers (or QQeueue is not a proper FIFO but I doubt it)... Is it so ?

If it is, this way I may give an answer to other people who are going through the same thing, and I would be interested in an efficient way of copying (or a more efficient of the above code). If not, I have no idea what's happening...

Thanks in advance.

Regards, Mister Mystère

Upvotes: 1

Views: 2180

Answers (2)

All cameras need a time of warming-up after the STREAM-ON (in v4l terminology) request, which can range from a few milliseconds to some seconds.

If you cannot afford such delay for the first frame, you'd better leave the camera on. Then, you might find yourself getting old frames. In such case you would need to flush the camera at the beginning. That is: quickly discarding every available [stale] frame while there are such. (you need to be able to know whether there are new images without blocking)

A different approach involves leaving a thread consuming those images, and using them only when needed.

Upvotes: 2

morynicz
morynicz

Reputation: 2342

The feed from the camera is queued in some sort of a buffer. I have struggled with this problem myself a while a go, solved it using a separate thread, which constantly takes the frames from the buffer, and if asked sends a frame to the main thread.

Upvotes: 2

Related Questions