简体   繁体   中英

Qt OpenCV Webcam Stream Opening and Closing

I have created a very simple UI using Qt which consists of a simple button and a label. When the button's clicked() signal is emitted, a function which captures a frame from a webcam using OpenCV is called. The code I am currently using to achieve this is:

cv::Mat MainWindow::captureFrame(int width, int height)
{

    //sets the width and height of the frame to be captured
    webcam.set(CV_CAP_PROP_FRAME_WIDTH, width);
    webcam.set(CV_CAP_PROP_FRAME_HEIGHT, height);

    //determine whether or not the webcam video stream was successfully initialized
    if(!webcam.isOpened())
    {
        qDebug() << "Camera initialization failed.";
    }

    //attempts to grab a frame from the webcam
    if (!webcam.grab()) {
        qDebug() << "Failed to capture frame.";
    }

    //attempts to read the grabbed frame and stores it in frame
    if (!webcam.read(frame)) {
        qDebug() << "Failed to read data from captured frame.";
    }

    return frame;
}

After a frame has been captured, it must be converted into a QImage in order to be displayed in the label. In order to achieve this, I use the following method:

QImage MainWindow::getQImageFromFrame(cv::Mat frame) {
    //converts the color model of the image from RGB to BGR because OpenCV uses BGR
    cv::cvtColor(frame, frame, CV_RGB2BGR);
    return QImage((uchar*) (frame.data), frame.cols, frame.rows, frame.step, QImage::Format_RGB888);
}

The constructor for my MainWaindow class looks like this:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    resize(1280, 720);
    move(QPoint(200, 200));
    webcam.open(0);
    fps = 1000/25;
    qTimer = new QTimer(this);
    qTimer->setInterval(fps);
    connect(qTimer, SIGNAL(timeout()), this, SLOT(displayFrame()));
}

The QTimer is supposed to display a frame by calling dislayFrame()

void MainWindow::displayFrame() {
    //capture a frame from the webcam
    frame = captureFrame(640, 360);
    image = getQImageFromFrame(frame);

    //set the image of the label to be the captured frame and resize the label appropriately
    ui->label->setPixmap(QPixmap::fromImage(image));
    ui->label->resize(ui->label->pixmap()->size());
}

each time its timeout() signal is emitted. However, while this appears to work to a degree, what actually happens is that the video capture stream from my webcam (a Logitech Quickcam Pro 9000 ) repeatedly opens and closes. This is evidenced by the fact that the blue ring, which indicates that the webcam is on, repeatedly flashes on and off. This leads to the refresh rate for the webcam video stream label to be very low, and is not desirable. Is there some way to make it so that the webcam stream remains open in order to prevent this "flickering" from occurring?

I seem to have solved the problem of the webcam stream opening and closing by removing the lines:

webcam.set(CV_CAP_PROP_FRAME_WIDTH, width);
webcam.set(CV_CAP_PROP_FRAME_HEIGHT, height);

from the captureFrame() function and setting the width and height of the frame to be captured in the MainWindow constructor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM