OpenCV4.X学习-视频相关

- libopencv_highgui4130.dll.a:

提供了简单易用的视频捕获、图像和视频编解码接口,以及简单的用户界面功能,如显示图像窗口等。

bash 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <opencv2/opencv.hpp>
#include <QDebug>

// 1. cv::namedWindow - 创建一个窗口
// 函数功能:创建一个指定名称的OpenCV窗口,窗口模式设置为可调整大小
void namedWindowExample() {
    // 创建名为"Example Window"的窗口,窗口模式为WINDOW_NORMAL,允许用户调整窗口大小
    cv::namedWindow("Example Window", cv::WINDOW_NORMAL);
    qDebug() << "窗口已成功创建";
}

// 2. cv::imshow - 在指定窗口中显示图像
// 函数功能:读取一张图像,并在指定的窗口中显示它
void imshowExample() {
    // 读取名为"example.jpg"的图像
    cv::Mat image = cv::imread("example.jpg");
    // 检查图像是否成功读取,如果图像为空,说明读取失败
    if (image.empty()) {
        qDebug() << "无法打开或找到图像";
        return;
    }
    // 创建名为"Display Image"的窗口,窗口模式为WINDOW_AUTOSIZE,窗口大小自动适应图像大小
    cv::namedWindow("Display Image", cv::WINDOW_AUTOSIZE);
    // 在"Display Image"窗口中显示图像
    cv::imshow("Display Image", image);
    // 等待用户按键,参数0表示无限等待
    cv::waitKey(0);
}

// 3. cv::waitKey - 等待按键事件
// 函数功能:读取一张图像,显示在窗口中,并等待用户按键,根据按键情况进行相应操作
void waitKeyExample() {
    // 读取名为"example.jpg"的图像
    cv::Mat image = cv::imread("example.jpg");
    // 检查图像是否成功读取,如果图像为空,说明读取失败
    if (image.empty()) {
        qDebug() << "无法打开或找到图像";
        return;
    }
    // 创建名为"Wait for Key"的窗口,窗口模式为WINDOW_AUTOSIZE,窗口大小自动适应图像大小
    cv::namedWindow("Wait for Key", cv::WINDOW_AUTOSIZE);
    // 在"Wait for Key"窗口中显示图像
    cv::imshow("Wait for Key", image);
    // 等待用户按键,参数0表示无限等待,返回用户按下的键的ASCII码值
    int key = cv::waitKey(0);
    // 判断用户是否按下了Esc键(ASCII码值为27)
    if (key == 27) {
        qDebug() << "按下Esc键,关闭窗口";
        // 销毁所有由OpenCV创建的窗口
        cv::destroyAllWindows();
    }
}

// 4. cv::destroyWindow - 销毁指定窗口
// 函数功能:创建一个窗口,然后销毁该指定名称的窗口
void destroyWindowExample() {
    // 创建名为"To Be Destroyed"的窗口,窗口模式为WINDOW_AUTOSIZE,窗口大小自动适应内容大小
    cv::namedWindow("To Be Destroyed", cv::WINDOW_AUTOSIZE);
    qDebug() << "窗口"To Be Destroyed"已创建";
    // 销毁名为"To Be Destroyed"的窗口
    cv::destroyWindow("To Be Destroyed");
    qDebug() << "窗口"To Be Destroyed"已销毁";
}

// 5. cv::destroyAllWindows - 销毁所有窗口
// 函数功能:创建两个窗口,然后销毁所有由OpenCV创建的窗口
void destroyAllWindowsExample() {
    // 创建名为"Window 1"的窗口,窗口模式为WINDOW_AUTOSIZE,窗口大小自动适应内容大小
    cv::namedWindow("Window 1", cv::WINDOW_AUTOSIZE);
    // 创建名为"Window 2"的窗口,窗口模式为WINDOW_AUTOSIZE,窗口大小自动适应内容大小
    cv::namedWindow("Window 2", cv::WINDOW_AUTOSIZE);
    qDebug() << "已创建两个窗口";
    // 销毁所有由OpenCV创建的窗口
    cv::destroyAllWindows();
    qDebug() << "所有窗口已销毁";
}

// 6. cv::createTrackbar - 创建一个轨迹栏
// 函数功能:读取一张图像,创建一个带有轨迹栏的窗口,通过轨迹栏调整图像的饱和度
void createTrackbarExample() {
    // 读取名为"example.jpg"的图像
    cv::Mat image = cv::imread("example.jpg");
    // 检查图像是否成功读取,如果图像为空,说明读取失败
    if (image.empty()) {
        qDebug() << "无法打开或找到图像";
        return;
    }
    // 初始化轨迹栏的当前值为0
    int value = 0;
    // 创建名为"Trackbar Window"的窗口,窗口模式为WINDOW_AUTOSIZE,窗口大小自动适应内容大小
    cv::namedWindow("Trackbar Window", cv::WINDOW_AUTOSIZE);
    // 在"Trackbar Window"窗口中创建一个名为"Trackbar"的轨迹栏,初始值为0,最大值为100
    cv::createTrackbar("Trackbar", "Trackbar Window", &value, 100);
    // 进入循环,不断根据轨迹栏的值调整图像并显示
    while (true) {
        // 克隆原始图像,避免直接修改原始图像
        cv::Mat modifiedImage = image.clone();
        // 将图像从BGR颜色空间转换到HSV颜色空间
        cv::cvtColor(modifiedImage, modifiedImage, cv::COLOR_BGR2HSV);
        // 将HSV图像分离成三个通道
        cv::Mat channels[3];
        cv::split(modifiedImage, channels);
        // 根据轨迹栏的值调整饱和度通道(第二个通道)
        channels[1] = channels[1] * (value / 100.0);
        // 合并调整后的通道
        cv::merge(channels, 3, modifiedImage);
        // 将图像从HSV颜色空间转换回BGR颜色空间
        cv::cvtColor(modifiedImage, modifiedImage, cv::COLOR_HSV2BGR);
        // 在"Trackbar Window"窗口中显示调整后的图像
        cv::imshow("Trackbar Window", modifiedImage);
        // 等待10毫秒,如果用户按下Esc键(ASCII码值为27),则退出循环
        if (cv::waitKey(10) == 27) {
            break;
        }
    }
    // 销毁所有由OpenCV创建的窗口
    cv::destroyAllWindows();
}

// 7. cv::getTrackbarPos - 获取轨迹栏的当前位置
// 函数功能:读取一张图像,创建一个带有轨迹栏的窗口,并不断获取并输出轨迹栏的当前位置
void getTrackbarPosExample() {
    // 读取名为"example.jpg"的图像
    cv::Mat image = cv::imread("example.jpg");
    // 检查图像是否成功读取,如果图像为空,说明读取失败
    if (image.empty()) {
        qDebug() << "无法打开或找到图像";
        return;
    }
    // 初始化轨迹栏的当前值为0
    int value = 0;
    // 创建名为"Get Trackbar Pos Window"的窗口,窗口模式为WINDOW_AUTOSIZE,窗口大小自动适应内容大小
    cv::namedWindow("Get Trackbar Pos Window", cv::WINDOW_AUTOSIZE);
    // 在"Get Trackbar Pos Window"窗口中创建一个名为"Trackbar"的轨迹栏,初始值为0,最大值为100
    cv::createTrackbar("Trackbar", "Get Trackbar Pos Window", &value, 100);
    // 进入循环,不断获取并输出轨迹栏的当前位置
    while (true) {
        // 获取名为"Trackbar"的轨迹栏在"Get Trackbar Pos Window"窗口中的当前位置
        int currentPos = cv::getTrackbarPos("Trackbar", "Get Trackbar Pos Window");
        qDebug() << "当前轨迹栏位置: " << currentPos;
        // 等待1000毫秒,如果用户按下Esc键(ASCII码值为27),则退出循环
        if (cv::waitKey(1000) == 27) {
            break;
        }
    }
    // 销毁所有由OpenCV创建的窗口
    cv::destroyAllWindows();
}

// 8. cv::setTrackbarPos - 设置轨迹栏的位置
// 函数功能:读取一张图像,创建一个带有轨迹栏的窗口,并将轨迹栏的位置设置为50
void setTrackbarPosExample() {
    // 读取名为"example.jpg"的图像
    cv::Mat image = cv::imread("example.jpg");
    // 检查图像是否成功读取,如果图像为空,说明读取失败
    if (image.empty()) {
        qDebug() << "无法打开或找到图像";
        return;
    }
    // 初始化轨迹栏的当前值为0
    int value = 0;
    // 创建名为"Set Trackbar Pos Window"的窗口,窗口模式为WINDOW_AUTOSIZE,窗口大小自动适应内容大小
    cv::namedWindow("Set Trackbar Pos Window", cv::WINDOW_AUTOSIZE);
    // 在"Set Trackbar Pos Window"窗口中创建一个名为"Trackbar"的轨迹栏,初始值为0,最大值为100
    cv::createTrackbar("Trackbar", "Set Trackbar Pos Window", &value, 100);
    // 将名为"Trackbar"的轨迹栏在"Set Trackbar Pos Window"窗口中的位置设置为50
    cv::setTrackbarPos("Trackbar", "Set Trackbar Pos Window", 50);
    // 进入循环,等待用户按下Esc键(ASCII码值为27),然后退出循环
    while (true) {
        if (cv::waitKey(10) == 27) {
            break;
        }
    }
    // 销毁所有由OpenCV创建的窗口
    cv::destroyAllWindows();
}

// 9. cv::imwrite - 将图像保存到文件
// 函数功能:读取一张图像,并将其保存为另一张图像文件
void imwriteExample() {
    // 读取名为"example.jpg"的图像
    cv::Mat image = cv::imread("example.jpg");
    // 检查图像是否成功读取,如果图像为空,说明读取失败
    if (image.empty()) {
        qDebug() << "无法打开或找到图像";
        return;
    }
    // 将图像保存为"saved_image.jpg",返回保存操作是否成功的布尔值
    bool success = cv::imwrite("saved_image.jpg", image);
    // 根据保存结果输出相应信息
    if (success) {
        qDebug() << "图像已成功保存";
    } else {
        qDebug() << "保存图像失败";
    }
}

// 10. cv::VideoCapture - 从摄像头或视频文件中捕获视频
// 函数功能:从默认摄像头捕获视频,并在窗口中显示每一帧,直到用户按下Esc键
void videoCaptureExample() {
    // 打开默认摄像头(参数0表示默认摄像头,也可以传入视频文件路径)
    cv::VideoCapture cap(0);
    // 检查摄像头是否成功打开
    if (!cap.isOpened()) {
        qDebug() << "打开视频流或文件时出错";
        return;
    }
    // 用于存储从摄像头捕获的每一帧图像
    cv::Mat frame;
    // 进入循环,不断从摄像头捕获帧并显示
    while (true) {
        // 从摄像头捕获一帧图像,存储在frame中
        cap >> frame;
        // 如果捕获的帧为空,说明视频结束或出现错误,退出循环
        if (frame.empty()) {
            break;
        }
        // 在名为"Video Stream"的窗口中显示当前帧
        cv::imshow("Video Stream", frame);
        // 等待25毫秒,如果用户按下Esc键(ASCII码值为27),则退出循环
        if (cv::waitKey(25) == 27) {
            break;
        }
    }
    // 释放摄像头资源
    cap.release();
    // 销毁所有由OpenCV创建的窗口
    cv::destroyAllWindows();
}

// 主测试函数
// 函数功能:调用各个示例函数,测试OpenCV的highgui模块的不同功能
int maintest() {
    namedWindowExample();
    imshowExample();
    waitKeyExample();
    destroyWindowExample();
    destroyAllWindowsExample();
    createTrackbarExample();
    getTrackbarPosExample();
    setTrackbarPosExample();
    imwriteExample();
    videoCaptureExample();
    return 0;
}

// MainWindow类的构造函数
// 功能:初始化MainWindow对象,设置用户界面并调用主测试函数
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    // 设置用户界面
    ui->setupUi(this);
    // 调用主测试函数
    maintest();
}

// MainWindow类的析构函数
// 功能:释放ui对象所占用的资源
MainWindow::~MainWindow()
{
    delete ui;
}

libopencv_video4130.dll.a:

视频分析模块,包含运动估计、背景减法、目标跟踪等算法,用于处理视频序列中的运动相关任务。

bash 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <opencv2/opencv.hpp>
#include <QDebug>


// 1. cv::VideoCapture::VideoCapture - 打开视频文件或摄像头
void videoCaptureOpenExample() {
    cv::VideoCapture cap(0); // 打开默认摄像头
    if (!cap.isOpened()) {
        qDebug() << "无法打开摄像头";
        return;
    }
    qDebug() << "摄像头已打开";
    cap.release();
}

// 2. cv::VideoCapture::read - 从视频捕获设备或文件中读取帧
void videoCaptureReadExample() {
    cv::VideoCapture cap("example.mp4"); // 打开视频文件
    if (!cap.isOpened()) {
        qDebug() << "无法打开视频文件";
        return;
    }
    cv::Mat frame;
    while (true) {
        cap.read(frame);
        if (frame.empty()) {
            break;
        }
        cv::imshow("视频帧", frame);
        if (cv::waitKey(25) == 27) { // 按Esc键退出
            break;
        }
    }
    cap.release();
    cv::destroyAllWindows();
}

// 3. cv::VideoWriter::VideoWriter - 创建视频写入对象
void videoWriterCreateExample() {
    cv::VideoCapture cap("example.mp4");
    if (!cap.isOpened()) {
        qDebug() << "无法打开视频文件";
        return;
    }
    int fourcc = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');
    cv::Size size(cap.get(cv::CAP_PROP_FRAME_WIDTH), cap.get(cv::CAP_PROP_FRAME_HEIGHT));
    cv::VideoWriter writer("output.avi", fourcc, cap.get(cv::CAP_PROP_FPS), size);
    if (!writer.isOpened()) {
        qDebug() << "无法创建视频写入对象";
        return;
    }
    qDebug() << "视频写入对象已创建";
    cap.release();
    writer.release();
}

// 4. cv::VideoWriter::write - 将帧写入视频文件
void videoWriterWriteExample() {
    cv::VideoCapture cap("example.mp4");
    if (!cap.isOpened()) {
        qDebug() << "无法打开视频文件";
        return;
    }
    int fourcc = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');
    cv::Size size(cap.get(cv::CAP_PROP_FRAME_WIDTH), cap.get(cv::CAP_PROP_FRAME_HEIGHT));
    cv::VideoWriter writer("output.avi", fourcc, cap.get(cv::CAP_PROP_FPS), size);
    if (!writer.isOpened()) {
        qDebug() << "无法创建视频写入对象";
        return;
    }
    cv::Mat frame;
    while (cap.read(frame)) {
        writer.write(frame);
    }
    qDebug() << "视频帧已写入";
    cap.release();
    writer.release();
}

// 5. cv::calcOpticalFlowFarneback - 计算稠密光流
void calcOpticalFlowFarnebackExample() {
    cv::VideoCapture cap("example.mp4");
    if (!cap.isOpened()) {
        qDebug() << "无法打开视频文件";
        return;
    }
    cv::Mat prevGray, gray, flow;
    cap >> prevGray;
    cv::cvtColor(prevGray, prevGray, cv::COLOR_BGR2GRAY);
    while (true) {
        cv::Mat frame;
        cap >> frame;
        if (frame.empty()) {
            break;
        }
        cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);
        cv::calcOpticalFlowFarneback(prevGray, gray, flow, 0.5, 3, 15, 3, 5, 1.2, 0);
        // 这里可以对光流数据flow进行进一步处理,例如可视化
        prevGray = gray.clone();
        if (cv::waitKey(25) == 27) {
            break;
        }
    }
    cap.release();
    cv::destroyAllWindows();
}

// 6. cv::createBackgroundSubtractorMOG2 - 创建MOG2背景减除器
void createBackgroundSubtractorMOG2Example() {
    cv::Ptr<cv::BackgroundSubtractorMOG2> pMOG2 = cv::createBackgroundSubtractorMOG2();
    if (!pMOG2) {
        qDebug() << "无法创建MOG2背景减除器";
        return;
    }
    qDebug() << "MOG2背景减除器已创建";
}

// 7. cv::BackgroundSubtractorMOG2::apply - 使用MOG2背景减除器处理帧
void backgroundSubtractorMOG2ApplyExample() {
    cv::VideoCapture cap("example.mp4");
    if (!cap.isOpened()) {
        qDebug() << "无法打开视频文件";
        return;
    }
    cv::Ptr<cv::BackgroundSubtractorMOG2> pMOG2 = cv::createBackgroundSubtractorMOG2();
    cv::Mat frame, fgMask;
    while (cap.read(frame)) {
        pMOG2->apply(frame, fgMask);
        // 这里可以对前景掩码fgMask进行进一步处理,例如显示或分析前景物体
        cv::imshow("前景掩码", fgMask);
        if (cv::waitKey(25) == 27) {
            break;
        }
    }
    cap.release();
    cv::destroyAllWindows();
}

// 8. cv::createBackgroundSubtractorKNN - 创建KNN背景减除器
void createBackgroundSubtractorKNNExample() {
    cv::Ptr<cv::BackgroundSubtractorKNN> pKNN = cv::createBackgroundSubtractorKNN();
    if (!pKNN) {
        qDebug() << "无法创建KNN背景减除器";
        return;
    }
    qDebug() << "KNN背景减除器已创建";
}

// 9. cv::BackgroundSubtractorKNN::apply - 使用KNN背景减除器处理帧
void backgroundSubtractorKNNApplyExample() {
    cv::VideoCapture cap("example.mp4");
    if (!cap.isOpened()) {
        qDebug() << "无法打开视频文件";
        return;
    }
    cv::Ptr<cv::BackgroundSubtractorKNN> pKNN = cv::createBackgroundSubtractorKNN();
    cv::Mat frame, fgMask;
    while (cap.read(frame)) {
        pKNN->apply(frame, fgMask);
        // 这里可以对前景掩码fgMask进行进一步处理,例如显示或分析前景物体
        cv::imshow("前景掩码", fgMask);
        if (cv::waitKey(25) == 27) {
            break;
        }
    }
    cap.release();
    cv::destroyAllWindows();
}

// 10. cv::VideoCapture::get - 获取视频捕获的属性
void videoCaptureGetExample() {
    cv::VideoCapture cap("example.mp4");
    if (!cap.isOpened()) {
        qDebug() << "无法打开视频文件";
        return;
    }
    double width = cap.get(cv::CAP_PROP_FRAME_WIDTH);
    double height = cap.get(cv::CAP_PROP_FRAME_HEIGHT);
    double fps = cap.get(cv::CAP_PROP_FPS);
    qDebug() << "视频宽度: " << width << ", 视频高度: " << height << ", 帧率: " << fps;
    cap.release();
}

int maintest() {
    videoCaptureOpenExample();
    videoCaptureReadExample();
    videoWriterCreateExample();
    videoWriterWriteExample();
    calcOpticalFlowFarnebackExample();
    createBackgroundSubtractorMOG2Example();
    backgroundSubtractorMOG2ApplyExample();
    createBackgroundSubtractorKNNExample();
    backgroundSubtractorKNNApplyExample();
    videoCaptureGetExample();
    return 0;
}

// MainWindow类的构造函数
// 功能:初始化MainWindow对象,设置用户界面并调用主测试函数
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    // 设置用户界面
    ui->setupUi(this);
    // 调用主测试函数
    maintest();
}

// MainWindow类的析构函数
// 功能:释放ui对象所占用的资源
MainWindow::~MainWindow()
{
    delete ui;
}

cv::VideoCapture::VideoCapture:用于打开视频文件或摄像头设备。

cv::VideoCapture::read:从打开的视频捕获设备或文件中读取一帧图像。

cv::VideoWriter::VideoWriter:创建一个视频写入对象,用于将帧写入视频文件。

cv::VideoWriter::write:将帧写入由 VideoWriter 创建的视频文件。

cv::calcOpticalFlowFarneback:计算稠密光流,用于分析视频中物体的运动。

cv::createBackgroundSubtractorMOG2:创建一个基于高斯混合模型的背景减除器。

cv::BackgroundSubtractorMOG2::apply:使用 MOG2 背景减除器处理视频帧,得到前景掩码。

cv::createBackgroundSubtractorKNN:创建一个基于 K 近邻的背景减除器。

cv::BackgroundSubtractorKNN::apply:使用 KNN 背景减除器处理视频帧,得到前景掩码。

cv::VideoCapture::get:获取视频捕获的属性,如宽度、高度、帧率等。

libopencv_videoio4130.dll.a:

视频输入输出模块,负责处理视频文件的读取和写入,以及摄像头视频流的捕获,支持多种视频格式和编解码器。

bash 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <opencv2/opencv.hpp>
#include <QDebug>

// 1. cv::VideoCapture::VideoCapture - 打开视频文件或摄像头
void openVideoSourceExample() {
    // 尝试打开默认摄像头
    cv::VideoCapture cap(0);
    if (!cap.isOpened()) {
        qDebug() << "无法打开摄像头";
        return;
    }
    qDebug() << "摄像头已成功打开";
    cap.release();
}

// 2. cv::VideoCapture::open - 打开视频文件或摄像头(另一种方式)
void openVideoSourceWithOpenFunctionExample() {
    cv::VideoCapture cap;
    // 尝试打开视频文件
    if (!cap.open("example.mp4")) {
        qDebug() << "无法打开视频文件";
        return;
    }
    qDebug() << "视频文件已成功打开";
    cap.release();
}

// 3. cv::VideoCapture::read - 从视频源读取帧
void readFrameFromVideoExample() {
    cv::VideoCapture cap("example.mp4");
    if (!cap.isOpened()) {
        qDebug() << "无法打开视频文件";
        return;
    }
    cv::Mat frame;
    while (true) {
        if (!cap.read(frame)) {
            break;
        }
        cv::imshow("视频帧", frame);
        if (cv::waitKey(25) == 27) { // 按Esc键退出
            break;
        }
    }
    cap.release();
    cv::destroyAllWindows();
}

// 4. cv::VideoCapture::get - 获取视频源的属性
void getVideoPropertiesExample() {
    cv::VideoCapture cap("example.mp4");
    if (!cap.isOpened()) {
        qDebug() << "无法打开视频文件";
        return;
    }
    double width = cap.get(cv::CAP_PROP_FRAME_WIDTH);
    double height = cap.get(cv::CAP_PROP_FRAME_HEIGHT);
    double fps = cap.get(cv::CAP_PROP_FPS);
    qDebug() << "视频宽度: " << width << ", 视频高度: " << height << ", 帧率: " << fps;
    cap.release();
}

// 5. cv::VideoCapture::set - 设置视频源的属性
void setVideoPropertiesExample() {
    cv::VideoCapture cap(0);
    if (!cap.isOpened()) {
        qDebug() << "无法打开摄像头";
        return;
    }
    // 设置摄像头分辨率为640x480
    cap.set(cv::CAP_PROP_FRAME_WIDTH, 640);
    cap.set(cv::CAP_PROP_FRAME_HEIGHT, 480);
    double newWidth = cap.get(cv::CAP_PROP_FRAME_WIDTH);
    double newHeight = cap.get(cv::CAP_PROP_FRAME_HEIGHT);
    qDebug() << "设置后的视频宽度: " << newWidth << ", 设置后的视频高度: " << newHeight;
    cap.release();
}

// 6. cv::VideoWriter::VideoWriter - 创建视频写入对象
void createVideoWriterExample() {
    cv::VideoCapture cap("example.mp4");
    if (!cap.isOpened()) {
        qDebug() << "无法打开视频文件";
        return;
    }
    int fourcc = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');
    cv::Size size(cap.get(cv::CAP_PROP_FRAME_WIDTH), cap.get(cv::CAP_PROP_FRAME_HEIGHT));
    cv::VideoWriter writer("output.avi", fourcc, cap.get(cv::CAP_PROP_FPS), size);
    if (!writer.isOpened()) {
        qDebug() << "无法创建视频写入对象";
        return;
    }
    qDebug() << "视频写入对象已成功创建";
    cap.release();
    writer.release();
}

// 7. cv::VideoWriter::open - 打开视频写入对象(另一种方式)
void openVideoWriterWithOpenFunctionExample() {
    cv::VideoWriter writer;
    cv::VideoCapture cap("example.mp4");
    if (!cap.isOpened()) {
        qDebug() << "无法打开视频文件";
        return;
    }
    int fourcc = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');
    cv::Size size(cap.get(cv::CAP_PROP_FRAME_WIDTH), cap.get(cv::CAP_PROP_FRAME_HEIGHT));
    if (!writer.open("output.avi", fourcc, cap.get(cv::CAP_PROP_FPS), size)) {
        qDebug() << "无法打开视频写入对象";
        return;
    }
    qDebug() << "视频写入对象已成功打开";
    cap.release();
    writer.release();
}

// 8. cv::VideoWriter::write - 将帧写入视频文件
void writeFrameToVideoExample() {
    cv::VideoCapture cap("example.mp4");
    if (!cap.isOpened()) {
        qDebug() << "无法打开视频文件";
        return;
    }
    int fourcc = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');
    cv::Size size(cap.get(cv::CAP_PROP_FRAME_WIDTH), cap.get(cv::CAP_PROP_FRAME_HEIGHT));
    cv::VideoWriter writer("output.avi", fourcc, cap.get(cv::CAP_PROP_FPS), size);
    if (!writer.isOpened()) {
        qDebug() << "无法创建视频写入对象";
        return;
    }
    cv::Mat frame;
    while (cap.read(frame)) {
        writer.write(frame);
    }
    qDebug() << "视频帧已成功写入";
    cap.release();
    writer.release();
}

// 9. cv::VideoWriter::isOpened - 检查视频写入对象是否打开
void checkVideoWriterOpenedExample() {
    cv::VideoWriter writer;
    cv::VideoCapture cap("example.mp4");
    if (!cap.isOpened()) {
        qDebug() << "无法打开视频文件";
        return;
    }
    int fourcc = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');
    cv::Size size(cap.get(cv::CAP_PROP_FRAME_WIDTH), cap.get(cv::CAP_PROP_FRAME_HEIGHT));
    if (!writer.open("output.avi", fourcc, cap.get(cv::CAP_PROP_FPS), size)) {
        qDebug() << "无法打开视频写入对象";
        return;
    }
    if (writer.isOpened()) {
        qDebug() << "视频写入对象已打开";
    } else {
        qDebug() << "视频写入对象未打开";
    }
    cap.release();
    writer.release();
}

// 10. cv::VideoCapture::release - 释放视频源
void releaseVideoSourceExample() {
    cv::VideoCapture cap(0);
    if (!cap.isOpened()) {
        qDebug() << "无法打开摄像头";
        return;
    }
    cap.release();
    qDebug() << "摄像头已释放";
}

int maintest() {
    openVideoSourceExample();
    openVideoSourceWithOpenFunctionExample();
    readFrameFromVideoExample();
    getVideoPropertiesExample();
    setVideoPropertiesExample();
    createVideoWriterExample();
    openVideoWriterWithOpenFunctionExample();
    writeFrameToVideoExample();
    checkVideoWriterOpenedExample();
    releaseVideoSourceExample();
    return 0;
}

// MainWindow类的构造函数
// 功能:初始化MainWindow对象,设置用户界面并调用主测试函数
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    // 设置用户界面
    ui->setupUi(this);
    // 调用主测试函数
    maintest();
}

// MainWindow类的析构函数
// 功能:释放ui对象所占用的资源
MainWindow::~MainWindow()
{
    delete ui;
}

cv::VideoCapture::VideoCapture 和 cv::VideoCapture::open:用于打开视频文件或摄像头设备,前者是构造函数方式,后者是成员函数方式。

cv::VideoCapture::read:从打开的视频源中读取一帧图像。

cv::VideoCapture::get:获取视频源的各种属性,如宽度、高度、帧率等。

cv::VideoCapture::set:设置视频源的属性,如分辨率等。

cv::VideoWriter::VideoWriter 和 cv::VideoWriter::open:用于创建视频写入对象,前者是构造函数方式,后者是成员函数方式。

cv::VideoWriter::write:将帧写入视频文件。

cv::VideoWriter::isOpened:检查视频写入对象是否成功打开。

cv::VideoCapture::release:释放视频源,关闭相关设备或文件。

相关推荐
雪风飞舞3 小时前
python根据音频生成柱状图
开发语言·python·音视频
万事可爱^3 小时前
LangChain v1.0学习笔记(4)—— 核心组件Models
人工智能·笔记·学习·langchain·大模型
狗狗学不会3 小时前
RK3588 极致性能:使用 Pybind11 封装 MPP 实现 Python 端 8 路视频硬件解码
人工智能·python·音视频
寄思~3 小时前
Excel 数据匹配工具 -笔记
笔记·python·学习·excel
朔北之忘 Clancy4 小时前
2020 年 6 月青少年软编等考 C 语言二级真题解析
c语言·开发语言·c++·学习·青少年编程·题解·尺取法
知识分享小能手4 小时前
Ubuntu入门学习教程,从入门到精通,Ubuntu 22.04 中安装 Docker 容器 —— 知识点详解(26)
学习·ubuntu·docker
知南x4 小时前
【物联网视频监控系统----韦东山老师视频总结】(4)流媒体方案的实现之ffmpeg
ffmpeg·音视频
开开心心_Every4 小时前
安卓做菜APP:家常菜谱详细步骤无广简洁
服务器·前端·python·学习·edge·django·powerpoint
wdfk_prog4 小时前
WIN11如何可以安装ISO
linux·笔记·学习