OpenCV QT,显示视频的帧(不使用while循环)

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

本文关键字:while 循环 QT 显示 视频 OpenCV      更新时间:2023-10-16

我有一个简单的个人项目,它使用QT和OpenCV框架在QLabel中显示视频。我知道如何转换为QImage并设置Pixmap。

但是,视频在 while 循环下运行得太快,当我检查时,无论我加载哪个视频,fps 都是 29 或 30。 为了解决这个问题,我还实现了一个QTimer,以便在加载视频时启动。 我不确定如何使用它以我需要设置的适当帧速率显示帧。

知道我该如何实现这一点吗?

我之前在我的项目中做过垫子到 QImage 的转换。

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;
}

用法可能是这样的

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);
}

据我所知,垫子图像应该是 ARGB32。它以 30 fps 的速度顺利工作。

我听说性能最好的解决方案是使用QOpenglWidget,但我不知道如何实现相同的功能。也许你可以看看。

我的旧存储库链接

显示代码-CPP

图像转换-CPP

使用 while-loop 没有错,你只需要正确计算帧率,然后为每个循环休眠,就像这样做:

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);
}

现在视频将以正常速率显示。