简体   繁体   中英

OpenCV QT, Displaying Frames of a Video (Not using a While Loop)

I have a simple personal project which uses QT and OpenCV frameworks to display a video in a QLabel. I know how to do the conversions into QImage and setting the Pixmap.

However, the video is running too fast under the while loop and when I checked the fps is either 29 or 30 no matter which video I load. To counter this, I have also implemented a QTimer to start when the video is loaded. I am not sure how to use that to display the frames with an appropriate framerate that I need to set.

Any Idea how i can implement this?

I have done mat to QImage conversion in my project earlier.

static QImage Mat2QImage(const cv::Mat3b &src) {
    QImage dest(src.cols, src.rows, QImage::Format_ARGB32);
    for (int y = 0; y < src.rows; ++y) {
        const cv::Vec3b *srcrow = src[y];
        QRgb *destrow = (QRgb*)dest.scanLine(y);
        for (int x = 0; x < src.cols; ++x) {
            destrow[x] = qRgba(srcrow[x][2], srcrow[x][1], srcrow[x][0], 255);
        }
    }
    return dest;
}

usage might be like this

void foo::timeout() // A slot which QTimer's timeout signal is connected to
{
    // I didn't tested the code but it should work
    Mat frame;
    m_cap >> frame;
    QImage img = Mat2QImage(frame);

    QPixmap pixmap = QPixmap::fromImage(img);
    ui->streamDisplay->setPixmap(pixmap);
}

As far as i remember, Mat image should be ARGB32. It had been worked at 30 fps smoothly.

I heard that the best performant solution is to use QOpenglWidget but i dont know how to implement the same functionality. Maybe you can take a look.

my older repo link

display-code-cpp

image-conversion-cpp

There is nothing wrong with using while-loop, you just need to calculate the frame rate correctly and then sleep for each loop, just do it like this:

int FPS = static_cast<int>(capture.get(cv::CAP_PROP_FPS));
uint delayTime = static_cast<uint>(1000 / FPS);
while(capture.read(frame))
{
    // process the frame 
    ...
    // now sleep (milli secconds)
    QThread::msleep(delayTime);
}

Now the video will be displayed at a normal rate.

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