OpenCV

技术栈
AI 框架
opencvc++python计算机视觉图像处理毕设

概览

OpenCV 技术栈概览

OpenCV(Open Source Computer Vision Library)是 Intel 于 1999 年发起的开源计算机视觉库,支持 C++ / Python / Java 等多语言接口。是图像处理和 CV 领域使用最广泛的库。

解决什么问题

  • 图像处理:滤波、边缘检测、形态学操作、色彩空间转换
  • 目标检测:人脸识别、物体跟踪、YOLO/SSD 等深度学习模型推理
  • 视频分析:运动检测、背景减除、光流法
  • 相机标定:棋盘格标定、畸变校正、立体视觉
  • 毕设场景:车牌识别、手势识别、人脸考勤、医学图像分析

关键特性

  • 2500+ 优化算法:涵盖经典 CV 和深度学习
  • 跨平台:Windows / Linux / macOS / Android / iOS
  • DNN 模块:支持加载 ONNX/TensorFlow/Caffe 模型
  • 硬件加速:CUDA、OpenCL、Vulkan 支持
  • 实时处理:C++ 核心高效的实时图像处理
  • 丰富的教程与社区:官方文档完善,示例丰富

安装

OpenCV 安装指南

1. 环境准备

要求 说明
操作系统 Windows 10+ / macOS 12+ / Linux (Ubuntu 20.04+)
C++ 编译器 MSVC 2019+ / GCC 9+ / Clang 12+(C++17 支持)
CMake 3.16+
磁盘空间 OpenCV 源码+编译约 2-5 GB

2. 安装命令

Python 方式(毕设推荐,最简单)

pip install opencv-python opencv-contrib-python
# 验证
python -c "import cv2; print(cv2.__version__)"

Linux (Ubuntu/Debian) — C++ 方式

sudo apt update
sudo apt install -y libopencv-dev
# 验证
pkg-config --modversion opencv4

macOS (Homebrew)

brew install opencv

Windows — 源码编译(推荐 vcpkg)

# 先安装 vcpkg
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg &;& .\bootstrap-vcpkg.bat
.\vcpkg integrate install
.\vcpkg install opencv4:x64-windows

从源码编译(通用方案)

git clone https://github.com/opencv/opencv.git
cd opencv &;& mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j$(nproc)
sudo make install

3. 常见安装问题

问题 解决方案
pip 安装太慢 pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple
cv2.imshow() 无响应 Linux 需安装 sudo apt install libgtk2.0-dev;或用 matplotlib 替代
编译时找不到 ffmpeg sudo apt install libavcodec-dev libavformat-dev
CMake 找不到 OpenCV 设置 OpenCV_DIR 为 build 目录或 /usr/local/lib/cmake/opencv4
版本冲突 创建虚拟环境:python -m venv venv && source venv/bin/activate

示例

OpenCV 图像处理入门——边缘检测与显示

目标

使用 OpenCV C++ 读取图片、高斯模糊 + Canny 边缘检测,并用窗口显示原图和结果。

完整代码

#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>

int main(int argc, char** argv) {
    // 1. 读取图像(支持命令行参数或默认测试图)
    cv::Mat src;
    if (argc > 1) {
        src = cv::imread(argv[1], cv::IMREAD_COLOR);
    } else {
        // 没有传入图片时生成一张渐变色测试图
        src = cv::Mat(480, 640, CV_8UC3);
        for (int y = 0; y < src.rows; y++) {
            for (int x = 0; x < src.cols; x++) {
                src.at<cv::Vec3b>(y, x) = cv::Vec3b(
                    (uchar)(y * 255 / src.rows),           // B
                    (uchar)(x * 255 / src.cols),           // G
                    (uchar)((x + y) * 255 / (src.rows + src.cols))  // R
                );
            }
        }
    }

    if (src.empty()) {
        std::cerr << "无法读取图像!" << std::endl;
        return -1;
    }

    std::cout << "图像尺寸: " << src.cols << "x" << src.rows
              << ", 通道数: " << src.channels() << std::endl;

    // 2. 灰度转换
    cv::Mat gray;
    cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);

    // 3. 高斯模糊(去噪)
    cv::Mat blurred;
    cv::GaussianBlur(gray, blurred, cv::Size(5, 5), 1.4);

    // 4. Canny 边缘检测
    cv::Mat edges;
    cv::Canny(blurred, edges, 50, 150);

    // 5. 显示结果
    cv::namedWindow("原图", cv::WINDOW_NORMAL);
    cv::namedWindow("边缘检测", cv::WINDOW_NORMAL);
    cv::resizeWindow("原图", 640, 480);
    cv::resizeWindow("边缘检测", 640, 480);
    cv::imshow("原图", src);
    cv::imshow("边缘检测", edges);

    std::cout << "按任意键退出..." << std::endl;
    cv::waitKey(0);

    // 6. 保存结果
    cv::imwrite("edges_output.jpg", edges);
    std::cout << "边缘图已保存为 edges_output.jpg" << std::endl;

    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
project(EdgeDetector LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(OpenCV REQUIRED)

add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE ${OpenCV_LIBS})

运行步骤

mkdir build &;& cd build
cmake ..
make -j$(nproc)

# 使用自定义图片
./EdgeDetector /path/to/photo.jpg

# 或直接运行(使用内置渐变色图)
./EdgeDetector

关键点

  • cv::imread() 读取图像,返回 cv::Mat 矩阵
  • cv::cvtColor() 色彩空间转换,边缘检测需灰度图
  • cv::GaussianBlur() 去噪,Canny 对噪声敏感
  • cv::Canny(blurred, edges, low, high) 双阈值法,low:high 推荐 1:3
  • cv::waitKey(0) 等待按键,0 表示无限等待

教程

OpenCV 毕设入门教程——计算机视觉实战

前言

OpenCV 是毕设中图像处理/计算机视觉方向的首选库。常见毕设题目:车牌识别、人脸考勤系统、手势识别、医学图像分割、车道线检测


第一章:OpenCV 核心数据结构

cv::Mat —— 一切图像的基础

cv::Mat img;                          // 空矩阵
img = cv::imread("photo.jpg");        // 读取图片
img = cv::Mat(480, 640, CV_8UC3);    // 创建 480×640 彩色图

常用属性:

  • img.rows / img.cols — 高/宽
  • img.channels() — 通道数(灰度=1,彩色=3)
  • img.type() — 数据类型

像素访问

// 灰度图
uchar pixel = gray.at<uchar>(y, x);

// 彩色图 (BGR)
cv::Vec3b pixel = img.at<cv::Vec3b>(y, x);
uchar blue = pixel[0], green = pixel[1], red = pixel[2];

第二章:毕设十大常用操作

1. 灰度化

cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);

2. 高斯模糊

cv::GaussianBlur(src, dst, cv::Size(5,5), 0);

3. 边缘检测

cv::Canny(gray, edges, 50, 150);

4. 二值化

cv::threshold(gray, binary, 127, 255, cv::THRESH_BINARY);
// 自适应二值化(光照不均时用)
cv::adaptiveThreshold(gray, binary, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C,
                      cv::THRESH_BINARY, 11, 2);

5. 形态学操作

cv::dilate(binary, dilated, kernel);   // 膨胀
cv::erode(binary, eroded, kernel);     // 腐蚀
cv::morphologyEx(binary, opened, cv::MORPH_OPEN, kernel);  // 开运算

6. 轮廓查找

std::vector<std::vector<cv::Point>> contours;
cv::findContours(binary, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
for (size_t i = 0; i < contours.size(); i++) {
    cv::drawContours(img, contours, i, cv::Scalar(0, 255, 0), 2);
}

7. 人脸检测

cv::CascadeClassifier face_cascade;
face_cascade.load("haarcascade_frontalface_default.xml");
std::vector<cv::Rect> faces;
face_cascade.detectMultiScale(gray, faces, 1.1, 3);

8. 颜色空间转换

cv::cvtColor(img, hsv, cv::COLOR_BGR2HSV);
// HSV 更适合颜色筛选:H(色调) 0-180, S(饱和度) 0-255, V(明度) 0-255

9. 图像缩放

cv::resize(src, dst, cv::Size(320, 240));

10. 视频读取

cv::VideoCapture cap(0);           // 摄像头
// cv::VideoCapture cap("video.mp4"); // 视频文件
cv::Mat frame;
while (cap.read(frame)) {
    cv::imshow("Video", frame);
    if (cv::waitKey(30) == 27) break;  // ESC 退出
}

第三章:毕设经典方案——车牌识别

简化流水线

读图 → 灰度 → 高斯模糊 → Canny边缘 → 轮廓查找 → 
筛选矩形轮廓(车牌区域)→ OCR 字符识别

关键代码片段

// 轮廓筛选:找到近似矩形的轮廓
for (const auto& contour : contours) {
    double peri = cv::arcLength(contour, true);
    std::vector<cv::Point> approx;
    cv::approxPolyDP(contour, approx, 0.02 * peri, true);
    // 4顶点 + 面积合理 → 可能是车牌
    if (approx.size() == 4 && cv::contourArea(approx) > 1000) {
        cv::Rect roi = cv::boundingRect(approx);
        cv::Mat plate = img(roi);
        // 送入 OCR...
    }
}

第四章:答辩准备

  1. 准备对比图:原图 vs 处理结果,效果最直观
  2. 录屏演示:实时摄像头识别比静态图片更有说服力
  3. 说明参数调优:展示你对算法理解的程度
  4. 备用方案:如果现场光线差,准备一段预先录好的视频

思考题

  1. Canny 的高低阈值如何影响边缘检测结果?
  2. 为什么颜色检测常用 HSV 而不是 RGB?
  3. 如何提升人脸检测在侧脸/遮挡情况下的准确率?

参考资料

  1. [1] Adrian Kaehler, Gary Bradski. Learning OpenCV 4. 2019.
  2. [2] OpenCV Team. OpenCV Documentation. 2024. https://docs.opencv.org/4.x/
  3. [3] Daniel Lélis Baggio, et al.. Mastering OpenCV with Practical Computer Vision Projects. 2012.