C语言OpenCV如何入门与实战应用?

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

OpenCV (Open Source Computer Vision Library) 是一个功能强大的开源计算机视觉和机器学习软件库,虽然它有 C++、Python 和 Java 等语言的接口,但其核心 API 仍然是 C 语言风格的,这使得它在嵌入式系统、对性能要求极高的场景以及需要最小化依赖的项目中非常受欢迎。

c 使用c语言的opencv
(图片来源网络,侵删)

为什么在 C 语言中使用 OpenCV?

  1. 性能:C 语言更接近底层,没有 C++ 的额外开销(如虚函数、异常处理等),在极端性能优化的场景下表现更佳。
  2. 兼容性:C 语言可以被 C++ 编译器编译,这意味着 C++ 项目可以轻松地调用 C 风格的 OpenCV 函数,实现与遗留 C 代码的集成。
  3. 依赖:C 语言版本的 OpenCV 通常比 C++ 版本链接的库更少,依赖更简单,适合资源受限的环境。
  4. 简洁性:对于一些基础的图像处理任务,C API 直接明了,没有 C++ STL 容器等复杂概念。

第一步:环境搭建

在使用 OpenCV 之前,你必须先在你的系统上安装它,这里以最常用的 Linux (Ubuntu) 和 Windows 为例。

在 Linux (Ubuntu/Debian) 上安装

打开终端,执行以下命令:

# 更新软件包列表
sudo apt update
# 安装必要的构建工具和依赖
sudo apt install build-essential cmake git
# 安装 OpenCV 的开发库
# pkg-config 工具用于在编译时自动找到 OpenCV 的头文件和库路径
sudo apt install libopencv-dev

安装完成后,你可以通过以下命令验证是否安装成功:

pkg-config --modversion opencv4
# 应该会输出 OpenCV 的版本号,4.5.5

在 Windows 上安装

在 Windows 上,推荐使用预编译的二进制包,这比从源码编译要简单得多。

c 使用c语言的opencv
(图片来源网络,侵删)
  1. 下载预编译包

    • 访问 OpenCV 官方发布页面:https://opencv.org/releases/
    • 找到最新的 "Source" 版本(8.0),点击 "source"。
    • 在 GitHub 页面中,找到 opencv -> opencv -> build -> x64 -> vc15vc16 (对应你的 Visual Studio 版本) 文件夹。
    • 下载 opencv-4.x.x-vc15-vc16.exe 这样的文件。
  2. 安装

    • 运行下载的 .exe 文件,它会使用 7-Zip 进行解压,选择一个解压路径,D:\opencv
  3. 配置环境变量

    • 将 OpenCV 的 bin 目录添加到系统的 PATH 环境变量中,如果你的解压路径是 D:\opencv\build\x64\vc15\bin,就将这个路径添加到 PATH
    • 这样,你的程序在运行时就能找到 OpenCV 的 DLL 文件。
  4. 获取 CMakeLists.txt 模板

    c 使用c语言的opencv
    (图片来源网络,侵删)
    • 在 Visual Studio 中创建一个新的 C++ 空项目(因为 C++ 编译器能编译 C 代码)。
    • 在项目根目录下创建一个 CMakeLists.txt 文件,内容如下(请根据你的实际安装路径修改):
    cmake_minimum_required(VERSION 3.10)
    project(MyOpenCVProject C CXX)
    # 指定 OpenCV 的路径
    set(OpenCV_DIR "D:/opencv/build/x64/vc15/lib")
    # 查找 OpenCV 包
    find_package(OpenCV REQUIRED)
    # 包含 OpenCV 的头文件
    include_directories(${OpenCV_INCLUDE_DIRS})
    # 添加可执行文件
    add_executable(main main.c)
    # 链接 OpenCV 库
    target_link_libraries(main ${OpenCV_LIBS})

第二步:编写你的第一个 C 程序 (Hello, Image)

下面我们通过一个完整的示例,从加载一张图片、显示它,再到保存一张处理后的图片,来学习 OpenCV 的 C API。

核心概念:IplImage 结构体

在 C API 中,图像的基本数据结构是 IplImage,它是一个 C 语言风格的结构体,包含了图像的所有信息,如图像的宽度、高度、像素数据指针、颜色通道数、深度等。

示例代码 (main.c)

#include <stdio.h>
#include <stdlib.h>
// 包含 OpenCV 的 C 头文件
#include <opencv/cv.h>
#include <opencv/highgui.h>
int main(int argc, char** argv) {
    // 1. 检查命令行参数
    if (argc != 2) {
        printf("Usage: %s <Image_Path>\n", argv[0]);
        return -1;
    }
    // 2. 加载一张图片
    // cvLoadImage 函数会分配内存并返回一个 IplImage* 指针
    // 参数1: 图片文件路径
    // 参数2: 加载模式,CV_LOAD_IMAGE_COLOR (1) 加载彩色图, CV_LOAD_IMAGE_GRAYSCALE (0) 加载灰度图, -1 加载原格式
    IplImage* src = cvLoadImage(argv[1], CV_LOAD_IMAGE_COLOR);
    if (!src) {
        printf("Error: Could not load image file: %s\n", argv[1]);
        return -1;
    }
    printf("Image loaded successfully.\n");
    printf("Image Size: %d x %d\n", src->width, src->height);
    // 3. 显示原始图片
    // cvNamedWindow 创建一个窗口来显示图像
    // 参数1: 窗口名称
    // 参数2: 窗口标志,CV_WINDOW_AUTOSIZE (0) 窗口大小自适应图像大小
    cvNamedWindow("Original Image", CV_WINDOW_AUTOSIZE);
    // cvShowImage 在指定窗口中显示图像
    // 参数1: 窗口名称
    // 参数2: 要显示的 IplImage 指针
    cvShowImage("Original Image", src);
    // 4. 图像处理:转换为灰度图
    // cvCreateImage 创建一个新的 IplImage 结构体
    // 参数1: 图像的尺寸
    // 参数2: 图像的位深度 (IPL_DEPTH_8U 是最常见的8位无符号整数)
    // 参数3: 通道数 (1表示灰度图)
    IplImage* gray = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
    // cvCvtColor 是颜色空间转换函数
    // 参数1: 源图像
    // 参数2: 目标图像
    // 参数3: 转换代码,CV_BGR2GRAY 表示从 BGR (OpenCV 默认) 转换为灰度
    cvCvtColor(src, gray, CV_BGR2GRAY);
    // 5. 显示处理后的灰度图
    cvNamedWindow("Grayscale Image", CV_WINDOW_AUTOSIZE);
    cvShowImage("Grayscale Image", gray);
    // 6. 保存处理后的图片
    // cvSaveImage 将图像保存到文件
    // 参数1: 文件名
    // 参数2: 要保存的图像指针
    // 参数3: 保存参数 (通常为0)
    if (cvSaveImage("grayscale_output.jpg", gray, 0)) {
        printf("Grayscale image saved as grayscale_output.jpg\n");
    } else {
        printf("Error: Could not save the grayscale image.\n");
    }
    // 7. 等待用户按键
    // cvWaitKey 会暂停程序,等待用户按下任意键,参数为0表示无限等待。
    // 如果参数大于0,则等待指定的毫秒数。
    printf("Press any key to exit...\n");
    cvWaitKey(0);
    // 8. 释放内存和销毁窗口
    // cvReleaseImage 释放 IplImage 结构体占用的内存
    cvReleaseImage(&src);
    cvReleaseImage(&gray);
    // cvDestroyAllWindows 销毁所有由 OpenCV 创建的窗口
    cvDestroyAllWindows();
    return 0;
}

编译和运行

在 Linux (Ubuntu) 上:

打开终端,进入 main.c 所在的目录,使用 gcc 进行编译:

# -g 添加调试信息
# `pkg-config --cflags opencv4` 会自动获取 OpenCV 的头文件路径
# `pkg-config --libs opencv4` 会自动获取 OpenCV 的库文件和链接选项
gcc main.c -o my_app $(pkg-config --cflags --libs opencv4)
# 运行程序 (假设你有一张名为lena.jpg的图片)
./my_app lena.jpg

在 Windows (Visual Studio + CMake) 上:

  1. 确保你的 lena.jpg 图片和 main.c 在项目目录下。

  2. 打开 "开发人员命令提示符 for VS"。

  3. 进入项目目录,创建一个 build 文件夹,并进入它。

  4. 运行 CMake 配置和生成:

    mkdir build
    cd build
    cmake .. -G "Visual Studio 16 2025" -A x64
    cmake --build . --config Release
  5. 编译成功后,可执行文件会在 build\Release\ 目录下,运行它:

    .\build\Release\my_app.exe lena.jpg

    你应该会看到两个窗口弹出,分别显示彩色和灰度图,并且当前目录下会生成 grayscale_output.jpg


常用 C API 函数速查表

功能类别 C API 函数 描述
图像加载与保存 cvLoadImage(filename, mode) 从文件加载图像,返回 IplImage*已废弃,但仍在C API中使用。
cvSaveImage(filename, image, params) 将图像保存到文件。
内存管理 cvCreateImage(size, depth, channels) 创建一个新的 IplImage
cvReleaseImage(image_ptr) 释放 IplImage 占用的内存。
窗口显示 cvNamedWindow(name, flags) 创建一个显示窗口。
cvShowImage(name, image) 在窗口中显示图像。
cvDestroyAllWindows() 销毁所有窗口。
用户输入 cvWaitKey(delay) 等待用户按键,用于控制程序流程。
图像处理 cvCvtColor(src, dst, code) 颜色空间转换 (如 BGR 到灰度、HSV 等)。
cvResize(src, dst, interpolation) 调整图像大小。
cvSmooth(src, dst, smooth_type, param1, param2) 图像平滑/模糊。
cvCanny(src, dst, threshold1, threshold2) Canny 边缘检测。
cvThreshold(src, dst, threshold, max_value, type) 图像二值化。
核心结构 IplImage C 风格的图像结构体。
CvRect 定义一个矩形区域。
CvSize 定义一个尺寸 (宽度和高度)。

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

虽然 OpenCV 的 C API 功能强大且仍然可用,但 OpenCV 官方强烈推荐使用 C++ API

为什么推荐 C++ API?

  1. 内存管理:C++ API 引入了 cv::Mat (Matrix) 类来替代 IplImagecv::Mat 是一个智能指针,当不再被引用时会自动释放内存,极大地减少了内存泄漏的风险。
  2. 性能cv::Mat 使用了更现代的内存管理技术(如写时复制 Copy-on-Write),在某些操作上比 IplImage 更高效。
  3. 现代 C++ 特性:C++ API 充分利用了 STL (标准模板库) 和 RAII (资源获取即初始化) 等现代 C++ 特性,代码更安全、更简洁、更易读。
  4. 功能完整:新功能和算法会优先以 C++ API 的形式提供。
  5. 社区支持:绝大多数最新的教程、文档和示例都是基于 C++ API 的。
  • 如果你正在维护旧的 C/C++ 项目,或者对性能有极致要求且环境资源受限,OpenCV 的 C API 是一个不错的选择。
  • 如果你正在开始一个新项目强烈建议你直接学习并使用 OpenCV 的 C++ API,它更安全、更现代,是社区的主流方向。

希望这份指南能帮助你顺利地在 C 语言项目中使用 OpenCV!

-- 展开阅读全文 --
头像
织梦自定义表单html
« 上一篇 01-29
c语言error c2213
下一篇 » 01-29

相关文章

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

目录[+]