1. 基本的视频读取和显示
// 创建视频捕获对象
cv::VideoCapture cap;

// 打开视频文件
cap.open("test_video.mp4");

// 检查是否成功打开
if (!cap.isOpened()) {
    std::cout << "无法打开视频文件!" << std::endl;
    return;
}

// 获取视频属性
double fps = cap.get(cv::CAP_PROP_FPS);
int width = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_WIDTH));
int height = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_HEIGHT));
int totalFrames = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_COUNT));

std::cout << "视频信息:" << std::endl;
// 1102 x 720
std::cout << "分辨率: " << width << " x " << height << std::endl;
// 25
std::cout << "帧率: " << fps << " FPS" << std::endl;
// 10206
std::cout << "总帧数: " << totalFrames << std::endl;
// 408.24
std::cout << "时长: " << totalFrames / fps << " 秒" << std::endl;

cv::Mat frame;
int frameCount = 0;

while (true) {
    // 读取一帧
    cap >> frame;

    // 检查帧是否为空
    if (frame.empty()) {
        std::cout << "视频播放结束!" << std::endl;
        break;
    }

    frameCount++;

    // 在帧上显示信息
    cv::putText(frame,
        "Frame: " + std::to_string(frameCount) +
        "/" + std::to_string(totalFrames),
        cv::Point(20, 40),
        cv::FONT_HERSHEY_SIMPLEX, 1,
        cv::Scalar(0, 255, 0), 2);

    // 显示帧
    cv::imshow("视频播放器", frame);

    // 按ESC退出,按空格暂停
    
    // 1000 / fps为每帧间隔时间
    int key = cv::waitKey(1000 / fps);
    // ESC退出程序
    if (key == 27) {
        break;
    }
    // 空格
    else if (key == 32) { 
        cv::waitKey(0);
    }
}

// 释放资源
cap.release();
cv::destroyAllWindows();
  1. 视频写入
// 输入视频
cv::VideoCapture cap("test_video.mp4");
if (!cap.isOpened()) {
    std::cout << "无法打开输入视频!" << std::endl;
    return;
}

// 获取输入视频属性
double fps = cap.get(cv::CAP_PROP_FPS);
int width = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_WIDTH));
int height = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_HEIGHT));

// 创建视频写入对象
cv::VideoWriter writer;

// 设置编码器和参数
int fourcc = cv::VideoWriter::fourcc('X', '2', '6', '4');       // H.264编码
// int fourcc = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');    // Motion-JPEG
// int fourcc = cv::VideoWriter::fourcc('X', 'V', 'I', 'D');    // XVID

writer.open("test_video.avi", fourcc, fps, cv::Size(width, height));

if (!writer.isOpened()) {
    std::cout << "无法创建输出视频文件!" << std::endl;
    return;
}

std::cout << "开始处理视频..." << std::endl;
std::cout << "输出格式: " << width << "x" << height << " @" << fps << "fps" << std::endl;

cv::Mat frame;
int processedFrames = 0;

while (true) {
    cap >> frame;
    if (frame.empty()) break;

    // 可选:对帧进行处理
    // cv::cvtColor(frame, frame, cv::COLOR_BGR2GRAY);
    // cv::cvtColor(frame, frame, cv::COLOR_GRAY2BGR);

    // 写入帧
    writer.write(frame);
    processedFrames++;

    // 显示进度
    if (processedFrames % 30 == 0) {
        std::cout << "已处理 " << processedFrames << " 帧" << std::endl;
    }

    // 显示处理过程
    cv::imshow("处理中", frame);
    // ESC退出
    if (cv::waitKey(1) == 27) break; 
}

std::cout << "视频处理完成! 共处理 " << processedFrames << " 帧" << std::endl;

cap.release();
writer.release();
cv::destroyAllWindows();
  1. 实时捕获摄像头:
// 打开默认摄像头
cv::VideoCapture cap(0);

if (!cap.isOpened()) {
    std::cout << "无法打开摄像头!" << std::endl;
    return;
}

// 设置摄像头参数
cap.set(cv::CAP_PROP_FRAME_WIDTH, 1280);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 720);
cap.set(cv::CAP_PROP_FPS, 30);

std::cout << "摄像头信息:" << std::endl;
std::cout << "分辨率: " << cap.get(cv::CAP_PROP_FRAME_WIDTH)
    << " x " << cap.get(cv::CAP_PROP_FRAME_HEIGHT) << std::endl;
std::cout << "帧率: " << cap.get(cv::CAP_PROP_FPS) << std::endl;

std::cout << "按ESC退出,按s保存图片,按r开始/停止录制" << std::endl;

cv::Mat frame;
bool recording = false;
cv::VideoWriter recorder;
int recordedFrames = 0;

while (true) {
    cap >> frame;
    if (frame.empty()) break;

    // 显示状态信息
    std::string status = recording ? "recording - " + std::to_string(recordedFrames) + "frames" : "ready";
    cv::putText(frame, status, cv::Point(20, 40),
        cv::FONT_HERSHEY_SIMPLEX, 0.7, cv::Scalar(0, 0, 255), 2);

    cv::putText(frame, "ESC:exit  s:take photo  r:recording", cv::Point(20, frame.rows - 20),
        cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(255, 255, 255), 1);

    cv::imshow("摄像头", frame);

    int key = cv::waitKey(1);
    if (key == 27) { // ESC
        break;
    }
    else if (key == 's' || key == 'S') { // 保存图片
        std::string filename = "capture_" + std::to_string(time(0)) + ".jpg";
        cv::imwrite(filename, frame);
        std::cout << "图片已保存: " << filename << std::endl;
    }
    else if (key == 'r' || key == 'R') { // 开始/停止录制
        if (!recording) {
            // 开始录制
            int fourcc = cv::VideoWriter::fourcc('X', '2', '6', '4');
            recorder.open("recording_" + std::to_string(time(0)) + ".avi",
                fourcc, 30.0, frame.size());
            if (recorder.isOpened()) {
                recording = true;
                recordedFrames = 0;
                std::cout << "开始录制..." << std::endl;
            }
        }
        else {
            // 停止录制
            recording = false;
            recorder.release();
            std::cout << "录制停止,共录制 " << recordedFrames << " 帧" << std::endl;
        }
    }

    // 录制帧
    if (recording) {
        recorder.write(frame);
        recordedFrames++;
    }
}

if (recording) {
    recorder.release();
}
cap.release();
cv::destroyAllWindows();