C++ OpenCV

下面将从基础概念、环境配置、核心数据结构、常用模块与典型用例四大方面,系统地介绍如何在 C++ 中使用 OpenCV。


1. 概述

OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉与机器学习库,提供了丰富的图像/视频处理算法。它以 C++ 为主,兼容 C、Python、Java 等接口,广泛应用于图像处理、实时视频分析、人脸识别、增强现实等领域。


2. 环境配置

  1. 下载与安装
    • 官网下载预编译包(Windows .exe/.zip,Linux 可用 aptyum 安装,macOS 可用 Homebrew:brew install opencv)。
    • 或者从 GitHub 源码编译,使用 CMake 自定义模块、启用 CUDA、TBB 等加速选项。
  2. CMake 配置示例cmake_minimum_required(VERSION 3.10) project(MyOpenCVProject) find_package(OpenCV REQUIRED) add_executable(main main.cpp) target_link_libraries(main PRIVATE ${OpenCV_LIBS})
    • find_package(OpenCV REQUIRED) 会在系统中查找已安装的 OpenCV,并定义变量 OpenCV_INCLUDE_DIRSOpenCV_LIBS 等。
    • 在 IDE(如 CLion、Visual Studio)中也可直接通过“添加库”向导引入 OpenCV。
  3. 头文件与命名空间#include <opencv2/opencv.hpp> using namespace cv;
    • 推荐一次性包含顶级头:<opencv2/opencv.hpp>
    • 如需精细控制,可单独包含模块头,例如 #include <opencv2/imgproc.hpp>#include <opencv2/highgui.hpp> 等。

3. 核心数据结构:cv::Mat

cv::Mat 是 OpenCV 中最核心的图像容器,封装了像素矩阵、尺寸、通道数、深度和内存管理。

// 创建空图像
Mat img1;
// 创建指定大小、3 通道、8 位无符号类型(BGR)的图像
Mat img2(480, 640, CV_8UC3, Scalar(0,0,255));  // 红色全画布
// 从文件读取
Mat img = imread("path/to/image.jpg", IMREAD_COLOR);
  • 访问像素Vec3b pixel = img.at<Vec3b>(row, col); pixel[0] = 255; // B 通道 img.at<Vec3b>(row, col) = pixel;
  • 常用类型宏
    • CV_8UCV_8UC3(8 位无符号,3 通道)
    • CV_32FCV_64F(浮点型)

4. 常用模块与函数

4.1 图像 I/O 与显示(highgui

Mat img = imread("lenna.png", IMREAD_GRAYSCALE);
if(img.empty()) { /* 读取失败 */ }
imshow("灰度图", img);
waitKey(0);  // 等待按键
  • imread:读取图像;
  • imwrite:保存图像;
  • imshow:显示窗口;
  • waitKey(int ms):等待指定毫秒或按键。

4.2 图像处理(imgproc

  1. 色彩空间转换Mat gray, hsv; cvtColor(img, gray, COLOR_BGR2GRAY); cvtColor(img, hsv, COLOR_BGR2HSV);
  2. 滤波与去噪Mat blur, gauss; blur = img.clone(); GaussianBlur(img, gauss, Size(5,5), 1.5);
  3. 边缘检测Mat edges; Canny(gray, edges, 50, 150);
  4. 形态学操作Mat bin, dilated; threshold(gray, bin, 100, 255, THRESH_BINARY); Mat kernel = getStructuringElement(MORPH_RECT, Size(3,3)); dilate(bin, dilated, kernel);

4.3 几何变换

// 缩放
Mat resized;
resize(img, resized, Size(), 0.5, 0.5);

// 旋转
Point2f center(img.cols/2.0f, img.rows/2.0f);
Mat M = getRotationMatrix2D(center, 45, 1.0);
Mat rotated;
warpAffine(img, rotated, M, img.size());

4.4 特征检测与匹配(features2d

Ptr<ORB> orb = ORB::create();
vector<KeyPoint> kp;
Mat desc;
orb->detectAndCompute(img, noArray(), kp, desc);

BFMatcher matcher(NORM_HAMMING);
vector<DMatch> matches;
matcher.match(desc1, desc2, matches);

4.5 视频处理(videoio & video

VideoCapture cap(0);  // 打开默认摄像头
if(!cap.isOpened()) { return -1; }
Mat frame;
while(true) {
    cap >> frame;
    if(frame.empty()) break;
    imshow("摄像头", frame);
    if(waitKey(30) == 27) break;  // 按 ESC 退出
}
cap.release();

5. 典型案例

5.1 实时人脸检测(Haar Cascades)

CascadeClassifier face_cascade("haarcascade_frontalface_default.xml");
VideoCapture cam(0);
Mat frame, gray;
while(cam.read(frame)) {
    cvtColor(frame, gray, COLOR_BGR2GRAY);
    vector<Rect> faces;
    face_cascade.detectMultiScale(gray, faces, 1.1, 3);
    for(auto& r : faces) {
        rectangle(frame, r, Scalar(0,255,0), 2);
    }
    imshow("Face", frame);
    if(waitKey(10) == 27) break;
}

5.2 透视变换(文档矫正)

// 假设已有 4 个角点 pts_src 和目标矩形宽高 w,h
vector<Point2f> dst = {{0,0}, {w-1,0}, {w-1,h-1}, {0,h-1}};
Mat H = getPerspectiveTransform(pts_src, dst);
Mat warped;
warpPerspective(src, warped, H, Size(w,h));

6. 性能优化与注意事项

  • 避免频繁分配:在循环外预创建 Mat
  • 使用 ROI:对图像子区域操作时,用 Mat roi = img(rect);
  • 并行加速:启用 TBB、OpenMP 或 CUDA 模块;
  • 零拷贝:注意 Mat 是引用计数的,拷贝只复制头部而不复制像素数据。

7. 拓展与深度学习支持

  • DNN 模块#include <opencv2/dnn.hpp>,可加载 TensorFlow、Caffe、ONNX 模型进行推理;
  • CUDA 加速:使用 opencv_cuda 系列接口,需在编译时启用;
  • 额外插件opencv_contrib 提供如 SIFT、SURF、ArUco、QR 码等更多算法。

通过以上结构化的讲解与示例,你可以快速上手并深入掌握 C++ OpenCV 编程,从基本图像处理到实时视频分析,再到深度学习模型推理与硬件加速,满足不同场景的视觉需求。

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注