QT版本:QT 6.3
OpenCV版本:opencv 4.6
编译环境:MSVC 2019 64bit
主要功能:通过OpenCV实现提取视频的单个视频帧图像或者全部视频帧图像,还可以获取视频的宽度、高度、帧率、帧数等,可自己添加。
opencv的配置我这里采用的MSVC的编译环境,可以直接导入外部库即可使用,部分步骤如下:
1. 右键项目,添加库,外部库
2. 选择库文件路径如下,选择包含路径如下
opencv方法实现类
opencv.h
#ifndef OPENCV_H
#define OPENCV_H
#include <QObject>
#include <opencv2/opencv.hpp>
#include <opencv2/video.hpp>
#include <QString>
#include <QImage>
#include <QList>
using namespace cv;
class opencv : public QObject
{
Q_OBJECT
public:
explicit opencv(QObject *parent = nullptr);
void setVideoCapture(VideoCapture cap);
VideoCapture getVideoCapture();
bool openVideo(QString path);
int getFrameNum();
int getFrameRate();
int getFrameWidth();
int getFrameHeight();
QImage getOneFrame(int posNum);
QList<QImage> getAllFrame();
QImage MatToQImage(const cv::Mat& mat);
void test01();
signals:
private:
VideoCapture m_cap;
};
#endif // OPENCV_H
opencv.cpp
#include "opencv.h"
#include <QDebug>
opencv::opencv(QObject *parent)
: QObject{parent}
{
/* template:
QImage img;
QList<QImage> imgList;
openVideo("F:/videoTest.mp4");
test01();
// 获取指定帧数的单个视频帧
img = getOneFrame(89);
img.save("imgimg.png");
// 获取全部视频帧
imgList = getAllFrame();
for(int i = 0; i < getFrameNum(); i++)
{
imgList.at(i).save(QString("img%1.png").arg(i));
}
*/
}
// 设置VideoCapture
void opencv::setVideoCapture(VideoCapture cap)
{
this->m_cap = cap;
}
// 获取VideoCapture
VideoCapture opencv::getVideoCapture()
{
return this->m_cap;
}
// 打开视频
bool opencv::openVideo(QString path)
{
this->m_cap.open(path.toStdString());
if(!m_cap.isOpened())
{
qDebug() << "video open fail";
return false;
}
return true;
}
// 获取总帧数
int opencv::getFrameNum()
{
return this->m_cap.get(CAP_PROP_FRAME_COUNT);
}
// 获取帧率
int opencv::getFrameRate()
{
return this->m_cap.get(CAP_PROP_FPS);
}
// 获取宽度
int opencv::getFrameWidth()
{
return this->m_cap.get(CAP_PROP_FRAME_WIDTH);
}
// 获取高度
int opencv::getFrameHeight()
{
return this->m_cap.get(CAP_PROP_FRAME_HEIGHT);
}
// 获取指定位置的视频帧
QImage opencv::getOneFrame(int posNum)
{
QImage img;
Mat frame;
if(!this->m_cap.isOpened())
{
qDebug() << "video open fail";
return img;
}
if(posNum >= getFrameNum())
{
qDebug() << "video frame position num overflow";
return img;
}
this->m_cap.set(CAP_PROP_POS_FRAMES, posNum);
if(!this->m_cap.grab())
{
qDebug() << "grab in opencv failed";
return img;
}
this->m_cap >> frame;
img = MatToQImage(frame);
return img;
}
// 获取全部视频帧
QList<QImage> opencv::getAllFrame()
{
QList<QImage> imgList;
for(int i = 0; i < getFrameNum(); i++)
{
imgList.insert(i, getOneFrame(i));
}
return imgList;
}
// Mat转图像
QImage opencv::MatToQImage(const cv::Mat& mat)
{
// 8-bits unsigned, NO. OF CHANNELS = 1
if (mat.type() == CV_8UC1)
{
QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
// Set the color table (used to translate colour indexes to qRgb values)
image.setColorCount(256);
for (int i = 0; i < 256; i++)
{
image.setColor(i, qRgb(i, i, i));
}
// Copy input Mat
uchar *pSrc = mat.data;
for (int row = 0; row < mat.rows; row++)
{
uchar *pDest = image.scanLine(row);
memcpy(pDest, pSrc, mat.cols);
pSrc += mat.step;
}
return image;
}
// 8-bits unsigned, NO. OF CHANNELS = 3
else if (mat.type() == CV_8UC3)
{
// Copy input Mat
const uchar *pSrc = (const uchar*)mat.data;
// Create QImage with same dimensions as input Mat
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
return image.rgbSwapped();
}
else if (mat.type() == CV_8UC4)
{
// Copy input Mat
const uchar *pSrc = (const uchar*)mat.data;
// Create QImage with same dimensions as input Mat
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
return image.copy();
}
else
{
return QImage();
}
}
void opencv::test01()
{
qDebug() << getFrameWidth() << getFrameHeight() << getFrameRate() << getFrameNum();
}
3. 编译后出现缺失文件提示,则将对应文件拷贝至编译文件内即可
项目资源免费下载地址:
qt6+opencv获取视频帧图像源码-QT文档类资源-CSDN下载
end