C语言如何实现VideoCapture视频捕获?

99ANYc3cd6
预计阅读时长 24 分钟
位置: 首页 C语言 正文

最常用和最强大的库是 OpenCV,我们将以 OpenCV 为核心,从基础到进阶,为你提供一份完整的 C 语言视频捕获指南。

c语言videocapture
(图片来源网络,侵删)

核心工具:OpenCV

OpenCV (Open Source Computer Vision Library) 是一个跨平台的计算机视觉和机器学习软件库,它包含了超过 2500 个优化的算法,涵盖了视频捕获、图像处理、特征检测、物体识别等方方面面。

为什么选择 OpenCV?

  • 功能强大:几乎你能想到的任何视频/图像处理功能,它都有。
  • 易于上手:API 设计相对直观,对于 C/C++ 友好。
  • 跨平台:支持 Windows, Linux, macOS, Android, iOS 等。
  • 社区活跃:文档丰富,教程和示例代码非常多。

第一步:安装 OpenCV

在开始编码之前,你必须在你的系统上安装 OpenCV。

在 Linux (Ubuntu/Debian) 上

# 更新包列表
sudo apt update
# 安装必要的构建工具和依赖
sudo apt install build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
# 克隆 OpenCV 源代码
git clone https://github.com/opencv/opencv.git
git clone https://github.com/opencv/opencv_contrib.git
# 创建一个构建目录
cd opencv
mkdir build && cd build
# 配置 CMake (指定安装路径和启用 contrib 模块)
cmake -D CMAKE_BUILD_TYPE=RELEASE \
      -D CMAKE_INSTALL_PREFIX=/usr/local \
      -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules \
      -D WITH_GTK=ON \
      -D WITH_OPENGL=ON \
      -D BUILD_EXAMPLES=ON ..
# 编译 (这需要一些时间)
make -j4
# 安装
sudo make install

在 Windows 上

  1. 推荐使用预编译库:从 OpenCV 官网 下载预编译好的版本(opencv-4.x.x-vc14_vc15.exe)。
  2. 安装:运行安装程序,它会解压文件到一个目录(C:\opencv)。
  3. 配置环境变量
    • C:\opencv\build\x64\vc15\bin (根据你的版本和编译器选择) 添加到系统的 PATH 环境变量中。
  4. 配置你的 IDE (如 Visual Studio)
    • 创建一个新的 C++ 控制台项目。
    • 右键点击项目 -> 属性
    • C/C++ -> 常规 -> 附加包含目录:添加 C:\opencv\build\include
    • 链接器 -> 常规 -> 附加库目录:添加 C:\opencv\build\x64\vc15\lib
    • 链接器 -> 输入 -> 附加依赖项:添加 opencv_world410d.lib (调试版) 或 opencv_world410.lib (发布版),注意版本号 410 可能不同。

第二步:编写 C 代码进行视频捕获

OpenCV 的 C API 和 C++ API 有些许不同,这里我们重点介绍 C API,因为它更符合你的问题。

c语言videocapture
(图片来源网络,侵删)

从摄像头捕获实时视频

这是最常见的用法,程序会打开你的默认摄像头,并逐帧显示视频流,直到你按下某个键('q')退出。

核心概念:

  • CvCapture: 结构体,代表一个视频捕获设备(摄像头或视频文件)。
  • cvCaptureFromCAM(): 打开摄像头并初始化 CvCapture 结构体。
  • cvQueryFrame(): 从 CvCapture 中捕获并解码一帧图像,返回一个 IplImage* 指针。注意: 这个函数返回的是指向内部缓冲区的指针,不要手动释放它,下一次调用 cvQueryFrame 时,旧帧的内存会被自动释放。
  • cvShowImage(): 在一个窗口中显示 IplImage
  • cvWaitKey(): 等待用户按键,这是控制视频播放和退出的关键,参数是等待的毫秒数,如果为 0,则无限期等待。

示例代码 (capture_camera.c):

#include <stdio.h>
#include <opencv/cv.h>
#include <opencv/highgui.h>
int main() {
    // 1. 初始化摄像头
    // 参数 -1 表示使用默认摄像头
    CvCapture* capture = cvCaptureFromCAM(-1);
    if (!capture) {
        fprintf(stderr, "无法打开摄像头!\n");
        return -1;
    }
    // 2. 创建一个窗口来显示视频
    cvNamedWindow("Camera Feed", CV_WINDOW_AUTOSIZE);
    printf("摄像头已打开,按 'q' 键退出...\n");
    // 3. 循环捕获并显示帧
    while (1) {
        // 捕获一帧
        IplImage* frame = cvQueryFrame(capture);
        // frame 为 NULL,说明视频结束或出错
        if (!frame) {
            printf("无法获取帧或视频已结束,\n");
            break;
        }
        // 显示当前帧
        cvShowImage("Camera Feed", frame);
        // 检查按键
        // cvWaitKey(1) 等待 1 毫秒,如果在这 1 毫秒内按下了 'q' 键,则返回 'q' 的 ASCII 码
        char c = cvWaitKey(1);
        if (c == 'q') {
            printf("用户请求退出,\n");
            break;
        }
    }
    // 4. 释放资源
    cvReleaseCapture(&capture);
    cvDestroyWindow("Camera Feed");
    return 0;
}

从视频文件捕获

从文件捕获和从摄像头捕获非常相似,只是初始化 CvCapture 的函数不同。

c语言videocapture
(图片来源网络,侵删)

核心概念:

  • cvCaptureFromFile(): 通过文件路径打开一个视频文件。

示例代码 (capture_file.c):

#include <stdio.h>
#include <opencv/cv.h>
#include <opencv/highgui.h>
int main() {
    // 1. 打开视频文件
    // 将 "my_video.mp4" 替换为你的视频文件路径
    CvCapture* capture = cvCaptureFromFile("my_video.mp4");
    if (!capture) {
        fprintf(stderr, "无法打开视频文件!\n");
        return -1;
    }
    // 2. 获取视频的帧率 (FPS)
    int fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
    printf("视频帧率: %d FPS\n", fps);
    // 3. 创建一个窗口
    cvNamedWindow("Video Player", CV_WINDOW_AUTOSIZE);
    printf("视频播放中,按 'q' 键退出...\n");
    // 4. 循环捕获并显示帧
    while (1) {
        IplImage* frame = cvQueryFrame(capture);
        if (!frame) {
            printf("视频播放完毕,\n");
            break;
        }
        cvShowImage("Video Player", frame);
        // 使用视频的帧率来控制播放速度
        // fps 为 0 (例如某些文件无法获取 fps),则使用默认延迟
        int delay = (fps > 0) ? (1000 / fps) : 30;
        char c = cvWaitKey(delay);
        if (c == 'q') {
            printf("用户请求退出,\n");
            break;
        }
    }
    // 5. 释放资源
    cvReleaseCapture(&capture);
    cvDestroyWindow("Video Player");
    return 0;
}

第三步:编译和运行代码

在 Linux 上

你需要链接 OpenCV 的库。

# 假设你的源文件是 capture_camera.c
gcc capture_camera.c -o capture_camera `pkg-config --cflags --libs opencv4`
# 运行
./capture_camera

注意:较新版本的 OpenCV (4.x) 可能使用 opencv4 而不是 opencv 作为 pkg-config 的名称,如果命令失败,请尝试 opencv

在 Windows (Visual Studio) 上

  1. 将你的 C 代码(capture_camera.c)添加到项目中。
  2. 确保项目属性中已经正确配置了 OpenCV 的包含目录和库目录(见安装步骤)。
  3. 链接器 -> 输入 -> 附加依赖项 中,确保有 opencv_world410d.lib (或对应版本)。
  4. 直接按 F5 编译并运行。

重要提示:C API vs. C++ API

虽然我们使用了 C API,但请注意:

  1. C API 已被标记为过时:OpenCV 的开发重点已经完全转移到 C++ API 上,C API 主要是为了向后兼容。
  2. C++ API 更现代、更安全
    • 使用 cv::VideoCapture 类代替 CvCapture*,它更安全,资源管理更方便(RAII)。
    • 使用 cv::Mat 类代替 IplImage*cv::Mat 是一个自动内存管理的图像类,避免了手动内存分配和释放的麻烦。
  3. 新项目建议:除非你有特殊的理由必须使用 C,否则强烈建议你直接学习 OpenCV 的 C++ API,它的学习曲线更平滑,代码也更健壮。

C++ API 的一个简单对比示例:

// C++ API 示例
#include <opencv2/opencv.hpp>
int main() {
    // cv::VideoCapture 是一个类,对象在离开作用域时会自动关闭
    cv::VideoCapture cap(0); // 打开默认摄像头
    if (!cap.isOpened()) {
        std::cerr << "无法打开摄像头!" << std::endl;
        return -1;
    }
    cv::namedWindow("C++ Feed", cv::WINDOW_AUTOSIZE);
    cv::Mat frame; // cv::Mat 是一个智能矩阵/图像类
    while (true) {
        cap >> frame; // 操作符 >> 重载,更简洁
        if (frame.empty()) {
            break;
        }
        cv::imshow("C++ Feed", frame);
        if (cv::waitKey(1) == 'q') {
            break;
        }
    }
    // cap 和 frame 会自动释放,无需手动操作
    return 0;
}
任务 C API 函数 C++ API 类/方法 说明
打开摄像头 cvCaptureFromCAM(-1) cv::VideoCapture cap(0); 初始化捕获对象
打开文件 cvCaptureFromFile("path.mp4") cv::VideoCapture cap("path.mp4"); 初始化捕获对象
读取一帧 IplImage* frame = cvQueryFrame(cap); cap >> frame; 获取并解码下一帧
显示图像 cvShowImage("Win", frame); cv::imshow("Win", frame); 在窗口中显示图像
等待按键 cvWaitKey(10); cv::waitKey(10); 处理窗口事件和延时
释放资源 cvReleaseCapture(&cap); cap.release(); 对象析构时自动调用

希望这份详细的指南能帮助你开始在 C 语言中使用 OpenCV 进行视频捕获!祝你编程愉快!

-- 展开阅读全文 --
头像
织梦网站模板本地安装教程
« 上一篇 01-04
dede 自定义字段 html
下一篇 » 01-04

相关文章

取消
微信二维码
支付宝二维码

目录[+]