opencv入门指南

OpenCV 入门指南 (C/C++):开启计算机视觉之旅 👁️‍🗨️

OpenCV (Open Source Computer Vision Library) 是一个开源的计算机视觉和机器学习软件库。它包含数千种优化的算法,为各种计算机视觉应用提供了丰富的工具集。无论你是想进行图像处理、物体检测、人脸识别,还是进行更复杂的视频分析,OpenCV 都是一个强大且灵活的选择。本指南将带你使用 C/C++ 语言入门 OpenCV。


📖 OpenCV 是什么?为什么选择它?

简单来说,OpenCV 是一套可以让你用编程方式“看”和“理解”图像与视频的工具箱

为什么选择 OpenCV?

  1. 功能强大且全面:提供了从基本的图像读取、显示、保存,到复杂的图像处理(滤波、边缘检测、形态学操作)、特征提取、物体检测、视频分析、相机标定、3D重建,乃至机器学习模块。
  2. 跨平台:支持 Windows, Linux, macOS, Android, iOS 等主流操作系统。
  3. 高性能:许多算法都针对速度进行了优化,并且可以利用多核处理器。对于实时应用,性能至关重要。
  4. C/C++ 接口:虽然 OpenCV 也支持 Python、Java 等语言,但其核心是用 C++ 编写的,提供了高效的 C/C++ API。对于追求性能的应用,C++ 是首选。
  5. 庞大的社区和丰富的文档:遇到问题时,很容易找到解决方案和学习资源。
  6. 商业友好型许可 (BSD):允许你在商业产品中免费使用。

🛠️ 环境搭建:准备好你的第一个 OpenCV 程序

在开始编码之前,你需要先安装 OpenCV。安装过程因操作系统而异。

基本步骤:

  1. 下载 OpenCV:

  2. 编译与安装:

    • Windows:
      • 你可以下载预编译的库 (pre-built libraries),解压后配置 Visual Studio 的包含目录 (Include Directories)、库目录 (Library Directories) 和链接器输入 (Linker Input)。
      • 或者使用 CMake 配合 Visual Studio (或其他编译器如 MinGW) 从源码编译。这能让你更好地控制编译选项。
    • Linux (Ubuntu/Debian 为例):
      • 可以通过包管理器安装:sudo apt update && sudo apt install libopencv-dev python3-opencv (这通常会安装一个较稳定但可能不是最新的版本)。
      • 推荐从源码编译安装,使用 CMake。这能确保你使用最新版本并可以自定义模块。你需要先安装必要的依赖项 (如 build-essential, cmake, git, libgtk2.0-dev, pkg-config, libavcodec-dev, libavformat-dev, libswscale-dev 等)。
    • macOS:
      • 可以使用 Homebrew:brew install opencv
      • 同样也可以从源码编译。
  3. 配置你的 IDE/编译器:

    • 你需要告诉你的编译器在哪里找到 OpenCV 的头文件 (.hpp, .h) 和库文件 (.lib, .dll on Windows; .so, .a on Linux/macOS)。

    • Visual Studio:

      • 项目属性 -> VC++ 目录 -> 包含目录:添加 path_to_opencv/build/include
      • 项目属性 -> VC++ 目录 -> 库目录:添加 path_to_opencv/build/your_compiler_arch/your_vc_version/lib (例如 x64/vc16/lib)。
      • 项目属性 -> 链接器 -> 输入 -> 附加依赖项:添加需要的 .lib 文件名 (例如 opencv_worldXYZ.lib,其中 XYZ 是版本号)。调试版通常带 ‘d’ 后缀,如 opencv_worldXYZd.lib
    • CMake (推荐):
      CMake 是一个跨平台的构建系统,非常适合 C++ 项目。创建一个 CMakeLists.txt 文件来管理你的项目编译:

      cmake_minimum_required(VERSION 3.10)
      project(MyOpenCVApp)
      
      set(CMAKE_CXX_STANDARD 11) # 或更高版本
      
      # 找到 OpenCV 包
      find_package(OpenCV REQUIRED)
      
      # 包含 OpenCV 头文件目录
      include_directories(${OpenCV_INCLUDE_DIRS})
      
      # 添加你的源文件
      add_executable(MyOpenCVApp main.cpp)
      
      # 链接 OpenCV 库
      target_link_libraries(MyOpenCVApp ${OpenCV_LIBS})
      

      然后使用 CMake 生成构建文件 (例如 Makefile 或 Visual Studio 项目),再进行编译。

      mkdir build
      cd build
      cmake ..
      make # 或者在 Visual Studio 中打开生成的 .sln 文件编译
      

环境变量 (尤其在 Windows 上):
确保包含 OpenCV bin 目录 (例如 path_to_opencv/build/your_compiler_arch/your_vc_version/bin) 的路径已添加到系统的 PATH 环境变量中,这样程序运行时才能找到所需的 .dll 文件。


🖼️ 核心概念与第一个程序:加载、显示和保存图像

OpenCV 中最核心的数据结构之一是 cv::Mat。它用于表示 n 维稠密数组,可以存储图像、特征向量、矩阵等。你可以把它想象成一个灵活的画布或数据容器。

我们的第一个程序:读取一张图片,显示它,然后保存它。

假设你有一张名为 input.jpg 的图片和你的 C++ 源文件 (例如 main.cpp) 在同一个目录下。

// main.cpp
#include <opencv2/core.hpp>     // 核心功能,如 cv::Mat
#include <opencv2/imgcodecs.hpp> // 图像读取和写入 (imread, imwrite)
#include <opencv2/highgui.hpp>  // GUI 功能 (imshow, waitKey, namedWindow)
#include <iostream>             // 用于控制台输出

int main() {
    // 1. 读取图像
    // cv::imread(filename, flags)
    //  - filename: 图像文件的路径
    //  - flags:
    //    - cv::IMREAD_COLOR: 以彩色模式加载图像 (默认)
    //    - cv::IMREAD_GRAYSCALE: 以灰度模式加载图像
    //    - cv::IMREAD_UNCHANGED: 加载包含 Alpha 通道的图像
    std::string imagePath = "input.jpg"; // 替换为你的图片路径
    cv::Mat image = cv::imread(imagePath, cv::IMREAD_COLOR);

    // 2. 检查图像是否成功加载
    if (image.empty()) {
        std::cerr << "错误:无法加载图像 " << imagePath << std::endl;
        return -1; // 返回错误码
    }

    // 3. 显示图像
    // cv::namedWindow(windowName, flags) - 创建一个窗口 (可选,但推荐)
    //  - windowName: 窗口的标题
    //  - flags:
    //    - cv::WINDOW_AUTOSIZE: 窗口大小根据图像自动调整 (默认)
    //    - cv::WINDOW_NORMAL: 窗口可以被用户调整大小
    std::string windowName = "我的第一个 OpenCV 图像";
    cv::namedWindow(windowName, cv::WINDOW_AUTOSIZE);

    // cv::imshow(windowName, imageMatrix) - 在指定窗口中显示图像
    cv::imshow(windowName, image);

    // 4. 等待按键
    // cv::waitKey(delay) - 等待指定的毫秒数,如果 delay <= 0,则无限等待直到用户按键
    // 返回值为按键的 ASCII 码,如果没有按键且超时则返回 -1
    std::cout << "图像已显示。按任意键关闭窗口并保存图像..." << std::endl;
    cv::waitKey(0); // 等待用户按键

    // 5. 保存图像
    // cv::imwrite(filename, imageMatrix)
    std::string outputImagePath = "output.png"; // 可以保存为不同格式,如 .png, .bmp 等
    bool success = cv::imwrite(outputImagePath, image);

    if (success) {
        std::cout << "图像已成功保存到 " << outputImagePath << std::endl;
    } else {
        std::cerr << "错误:无法保存图像到 " << outputImagePath << std::endl;
    }

    // 6. 关闭所有 OpenCV 创建的窗口 (可选,程序结束时会自动关闭)
    cv::destroyAllWindows();

    return 0; // 程序成功结束
}

代码解释:

  1. 包含头文件
    • opencv2/core.hpp: 包含了 cv::Mat 等核心数据结构的定义。
    • opencv2/imgcodecs.hpp: 包含了图像编解码函数,如 cv::imread() (读取) 和 cv::imwrite() (保存)。
    • opencv2/highgui.hpp: 包含了高级 GUI 函数,如 cv::namedWindow() (创建窗口)、cv::imshow() (显示图像) 和 cv::waitKey() (等待按键)。
  2. cv::Mat image = cv::imread(imagePath, cv::IMREAD_COLOR);
    • 创建一个 cv::Mat 对象 image
    • cv::imread() 函数尝试从 imagePath 指定的路径加载图像。
    • cv::IMREAD_COLOR 表示以彩色模式加载。
  3. if (image.empty())
    • 这是一个非常重要的错误检查。如果 cv::imread() 找不到文件或文件格式不支持,它会返回一个空的 cv::Mat 对象。.empty() 方法可以检查 cv::Mat 是否为空。
  4. cv::namedWindow(windowName, cv::WINDOW_AUTOSIZE);
    • 创建一个名为 “我的第一个 OpenCV 图像” 的窗口。cv::WINDOW_AUTOSIZE 使窗口大小自动适应图像。
  5. cv::imshow(windowName, image);
    • 在之前创建的窗口中显示 image
  6. cv::waitKey(0);
    • 这是使图像窗口保持可见的关键。cv::waitKey() 等待用户按键。参数 0 表示无限期等待。如果没有这个函数,窗口会一闪而过。
  7. cv::imwrite(outputImagePath, image);
    • image 对象中的图像数据保存到名为 output.png 的文件中。OpenCV 会根据文件扩展名自动选择编码格式。
  8. cv::destroyAllWindows();
    • 关闭所有由 OpenCV 创建的窗口。虽然程序结束时通常会自动清理,但这是一种良好的编程习惯。

编译和运行:

  • 使用 CMake:
    # 假设你的 CMakeLists.txt 和 main.cpp 在同一目录
    mkdir build
    cd build
    cmake ..
    make        # 或者 cmake --build .  (在 Windows 上,如果生成的是 Visual Studio 项目,则用 VS 打开并编译)
    ./MyOpenCVApp # 运行程序
    
  • 直接使用 g++ (Linux/macOS 示例,需要正确配置 pkg-config 或手动指定包含和库路径):
    g++ main.cpp -o MyOpenCVApp `pkg-config --cflags --libs opencv4` # opencv4 可能需要根据你的版本调整
    ./MyOpenCVApp
    
    (对于 pkg-config opencv4 不可用的情况,你需要手动指定 -I-L 标志以及 -l 链接库,例如:g++ main.cpp -o MyOpenCVApp -I/usr/local/include/opencv4 -L/usr/local/lib -lopencv_core -lopencv_imgcodecs -lopencv_highgui)

🎨 基本图像操作

掌握了图像的读写和显示后,我们来看看一些基本的图像操作。

1. 获取图像属性

cv::Mat 对象包含很多关于图像的信息:

#include <opencv2/opencv.hpp> // 包含所有常用模块
#include <iostream>

int main() {
    cv::Mat image = cv::imread("input.jpg");
    if (image.empty()) {
        std::cerr << "无法加载图像!" << std::endl;
        return -1;
    }

    // 获取图像尺寸
    int rows = image.rows; // 高度 (像素)
    int cols = image.cols; // 宽度 (像素)
    std::cout << "图像尺寸: " << cols << "x" << rows << std::endl;

    // 获取图像通道数
    int channels = image.channels();
    std::cout << "图像通道数: " << channels << std::endl;
    // 彩色图像通常有 3 个通道 (BGR),灰度图像有 1 个通道

    // 获取图像深度 (每个通道中像素值的类型)
    // CV_8U (8位无符号整数), CV_16S (16位有符号整数), CV_32F (32位浮点数) 等
    int depth = image.depth();
    std::cout << "图像深度类型: ";
    switch (depth) {
        case CV_8U:  std::cout << "CV_8U (8-bit unsigned)"; break;
        case CV_8S:  std::cout << "CV_8S (8-bit signed)"; break;
        case CV_16U: std::cout << "CV_16U (16-bit unsigned)"; break;
        case CV_16S: std::cout << "CV_16S (16-bit signed)"; break;
        case CV_32S: std::cout << "CV_32S (32-bit signed)"; break;
        case CV_32F: std::cout << "CV_32F (32-bit float)"; break;
        case CV_64F: std::cout << "CV_64F (64-bit float)"; break;
        default:     std::cout << "未知"; break;
    }
    std::cout << std::endl;

    // 获取图像类型 (深度 + 通道数的组合)
    // 例如 CV_8UC3 表示 8位无符号整数,3通道
    int type = image.type();
    std::cout << "图像类型 (如 CV_8UC3): " << type << std::endl;
    // 你可以用 image.type() == CV_8UC3 来检查

    cv::imshow("属性演示", image);
    cv::waitKey(0);
    cv::destroyAllWindows();
    return 0;
}

2. 颜色空间转换

最常见的转换是将彩色图像转换为灰度图像。

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp> // 图像处理模块,包含颜色转换

int main() {
    cv::Mat colorImage = cv::imread("input.jpg");
    if (colorImage.empty()) {
        std::cerr << "无法加载彩色图像!" << std::endl;
        return -1;
    }

    cv::Mat grayImage;
    // cv::cvtColor(sourceImage, destinationImage, conversionCode)
    cv::cvtColor(colorImage, grayImage, cv::COLOR_BGR2GRAY);
    // 注意:OpenCV 默认以 BGR 顺序加载彩色图像,而不是 RGB

    cv::imshow("彩色图像", colorImage);
    cv::imshow("灰度图像", grayImage);
    cv::waitKey(0);

    cv::imwrite("gray_output.jpg", grayImage);
    std::cout << "灰度图像已保存为 gray_output.jpg" << std::endl;

    cv::destroyAllWindows();
    return 0;
}

其他常见的颜色空间转换包括 COLOR_BGR2HSV, COLOR_BGR2Lab 等。

3. 图像缩放 (Resizing)

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>

int main() {
    cv::Mat originalImage = cv::imread("input.jpg");
    if (originalImage.empty()) {
        std::cerr << "无法加载图像!" << std::endl;
        return -1;
    }

    cv::Mat resizedImage;
    // 方法1: 指定目标尺寸
    cv::Size newSize(300, 200); // 宽 300, 高 200
    // cv::resize(source, destination, dsize, fx, fy, interpolation)
    // dsize: 目标尺寸
    // fx, fy: x 和 y 方向的缩放因子 (如果 dsize 非零,则忽略)
    // interpolation: 插值方法
    //   - cv::INTER_LINEAR: 线性插值 (常用)
    //   - cv::INTER_NEAREST: 最近邻插值
    //   - cv::INTER_CUBIC: 双三次插值 (效果好但慢)
    cv::resize(originalImage, resizedImage, newSize, 0, 0, cv::INTER_LINEAR);

    cv::imshow("原始图像", originalImage);
    cv::imshow("缩放图像 (指定尺寸)", resizedImage);
    cv::waitKey(0);

    // 方法2: 指定缩放因子
    cv::Mat scaledImage;
    double scaleX = 0.5; // 缩小到50%宽度
    double scaleY = 0.5; // 缩小到50%高度
    cv::resize(originalImage, scaledImage, cv::Size(), scaleX, scaleY, cv::INTER_LINEAR);

    cv::imshow("缩放图像 (指定因子)", scaledImage);
    cv::waitKey(0);

    cv::destroyAllWindows();
    return 0;
}

4. 图像模糊 (Blurring/Smoothing)

模糊可以用于降噪或作为某些算法的预处理步骤。高斯模糊是最常用的模糊方法之一。

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>

int main() {
    cv::Mat image = cv::imread("input.jpg");
    if (image.empty()) {
        std::cerr << "无法加载图像!" << std::endl;
        return -1;
    }

    cv::Mat blurredImage;
    // cv::GaussianBlur(source, destination, ksize, sigmaX, sigmaY, borderType)
    // ksize: 高斯核大小,必须是正奇数,如 cv::Size(5, 5)
    // sigmaX: X方向的高斯核标准差
    // sigmaY: Y方向的高斯核标准差 (如果为0,则从 sigmaX 计算;如果都为0,则从 ksize 计算)
    cv::GaussianBlur(image, blurredImage, cv::Size(15, 15), 0);

    cv::imshow("原始图像", image);
    cv::imshow("高斯模糊", blurredImage);
    cv::waitKey(0);
    cv::destroyAllWindows();
    return 0;
}

5. 边缘检测 (Edge Detection)

Canny 边缘检测是一种流行的边缘检测算法。

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>

int main() {
    cv::Mat image = cv::imread("input.jpg", cv::IMREAD_GRAYSCALE); // Canny 通常在灰度图上操作
    if (image.empty()) {
        std::cerr << "无法加载图像!" << std::endl;
        return -1;
    }

    cv::Mat edges;
    // cv::Canny(source, destination, threshold1, threshold2, apertureSize, L2gradient)
    // threshold1: 第一个阈值 (低阈值)
    // threshold2: 第二个阈值 (高阈值)
    // apertureSize: Sobel 算子的孔径大小 (通常为 3)
    // L2gradient: 是否使用更精确的 L2 范数计算图像梯度幅值 (默认 false)
    cv::Canny(image, edges, 50, 150);

    cv::imshow("原始灰度图", image);
    cv::imshow("Canny 边缘", edges);
    cv::waitKey(0);
    cv::destroyAllWindows();
    return 0;
}

📹 处理视频

OpenCV 同样可以轻松处理视频,无论是从文件读取还是从摄像头实时捕获。

1. 从文件读取视频

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

int main() {
    // 打开视频文件
    cv::VideoCapture cap("my_video.mp4"); // 替换为你的视频文件路径

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

    cv::Mat frame;
    std::string windowName = "视频播放";
    cv::namedWindow(windowName, cv::WINDOW_AUTOSIZE);

    while (true) {
        // 读取一帧
        // cap.read(frame) 或 cap >> frame;
        bool success = cap.read(frame);

        // 如果读取失败 (例如视频结束),则退出循环
        if (!success) {
            std::cout << "视频播放完毕或读取帧失败。" << std::endl;
            break;
        }

        // 在这里可以对 frame 进行处理,例如转灰度、边缘检测等
        // cv::cvtColor(frame, frame, cv::COLOR_BGR2GRAY);

        // 显示帧
        cv::imshow(windowName, frame);

        // 等待 25毫秒,如果按下 'q' 键或 ESC 键则退出
        // 视频的帧率通常是 25-30 fps,所以等待时间是 1000/fps
        char key = (char)cv::waitKey(25);
        if (key == 'q' || key == 27) { // 27 是 ESC 键的 ASCII 码
            break;
        }
    }

    // 释放 VideoCapture 对象
    cap.release();
    // 关闭所有窗口
    cv::destroyAllWindows();

    return 0;
}

2. 从摄像头捕获视频

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

int main() {
    // 打开默认摄像头 (通常索引为 0)
    // 如果有多个摄像头,可以尝试 1, 2, ...
    cv::VideoCapture cap(0);

    if (!cap.isOpened()) {
        std::cerr << "错误:无法打开摄像头!" << std::endl;
        return -1;
    }

    // 可以设置摄像头的属性,例如帧的宽度和高度
    // cap.set(cv::CAP_PROP_FRAME_WIDTH, 640);
    // cap.set(cv::CAP_PROP_FRAME_HEIGHT, 480);

    cv::Mat frame;
    std::string windowName = "摄像头实时画面";
    cv::namedWindow(windowName, cv::WINDOW_AUTOSIZE);

    std::cout << "按 'q' 或 ESC 键退出..." << std::endl;

    while (true) {
        cap >> frame; // 或者 cap.read(frame);

        if (frame.empty()) {
            std::cerr << "错误:捕获到空帧!" << std::endl;
            break;
        }

        // 对帧进行处理 (可选)
        // 例如,水平翻转图像,因为摄像头画面通常是镜像的
        cv::Mat flippedFrame;
        cv::flip(frame, flippedFrame, 1); // 1 表示水平翻转, 0 表示垂直, -1 表示都翻转

        cv::imshow(windowName, flippedFrame); // 显示翻转后的帧

        char key = (char)cv::waitKey(1); // 等待 1ms,几乎是实时
        if (key == 'q' || key == 27) {
            break;
        }
    }

    cap.release();
    cv::destroyAllWindows();
    return 0;
}

🖌️ 在图像上绘制图形和文本

OpenCV 提供了在图像上绘制点、线、矩形、圆形、文本等功能,这对于标注、调试和结果可视化非常有用。

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp> // 绘图函数主要在这里

int main() {
    // 创建一个黑色背景图像
    cv::Mat canvas = cv::Mat::zeros(cv::Size(500, 500), CV_8UC3); // 500x500, 3通道 (BGR)

    // 1. 绘制直线
    // cv::line(image, pt1, pt2, color, thickness, lineType, shift)
    cv::Point pt1(50, 50);
    cv::Point pt2(450, 50);
    cv::Scalar lineColor(0, 255, 0); // BGR 格式:绿色
    int thickness = 2;
    cv::line(canvas, pt1, pt2, lineColor, thickness);

    // 2. 绘制矩形
    // cv::rectangle(image, pt1, pt2, color, thickness, lineType, shift)
    // pt1: 左上角点, pt2: 右下角点
    // 或者 cv::rectangle(image, Rect, color, thickness, ...)
    cv::Rect rect(100, 100, 200, 150); // x, y, width, height
    cv::Scalar rectColor(255, 0, 0);   // 蓝色
    cv::rectangle(canvas, rect, rectColor, thickness);
    // 绘制填充矩形
    cv::rectangle(canvas, cv::Point(120,120), cv::Point(180,180), cv::Scalar(255,255,0), cv::FILLED);


    // 3. 绘制圆形
    // cv::circle(image, center, radius, color, thickness, lineType, shift)
    cv::Point center(350, 350);
    int radius = 50;
    cv::Scalar circleColor(0, 0, 255); // 红色
    cv::circle(canvas, center, radius, circleColor, thickness);
    // 绘制填充圆形
    cv::circle(canvas, cv::Point(350,150), 30, cv::Scalar(0,255,255), cv::FILLED);


    // 4. 绘制椭圆
    // cv::ellipse(image, center, axes, angle, startAngle, endAngle, color, thickness, ...)
    cv::Point ellipseCenter(150, 400);
    cv::Size axes(70, 30); // 长轴和短轴长度
    double angle = 45; // 旋转角度
    double startAngle = 0;
    double endAngle = 360; // 完整的椭圆
    cv::Scalar ellipseColor(255, 0, 255); // 紫色
    cv::ellipse(canvas, ellipseCenter, axes, angle, startAngle, endAngle, ellipseColor, thickness);

    // 5. 放置文本
    // cv::putText(image, text, org, fontFace, fontScale, color, thickness, lineType, bottomLeftOrigin)
    std::string text = "OpenCV Rocks!";
    cv::Point textOrg(50, 480); // 文本左下角起始点
    int fontFace = cv::FONT_HERSHEY_SIMPLEX;
    double fontScale = 1.0;
    cv::Scalar textColor(255, 255, 255); // 白色
    cv::putText(canvas, text, textOrg, fontFace, fontScale, textColor, thickness);

    cv::imshow("绘图演示", canvas);
    cv::waitKey(0);
    cv::destroyAllWindows();

    return 0;
}

🚀 接下来学什么?

恭喜你!你已经迈出了 OpenCV (C/C++) 学习的第一步。这只是冰山一角,OpenCV 的世界非常广阔。

建议的学习路径:

  1. 深入 cv::Mat:理解其内存管理、ROI (Region of Interest)、拷贝和克隆的区别。
  2. 像素级操作:学习如何直接访问和修改图像的像素值 (使用 .at<type>(row, col) 或指针)。
  3. 更多图像处理技术
    • 形态学操作 (腐蚀、膨胀、开运算、闭运算)
    • 直方图计算与均衡化
    • 图像阈值化 (二值化)
    • 模板匹配
    • 霍夫变换 (检测直线和圆)
  4. 特征提取与匹配:SIFT, SURF, ORB, AKAZE 等特征点检测与描述。
  5. 物体检测:Haar 级联分类器 (用于人脸检测等),以及更现代的基于深度学习的方法 (OpenCV 的 DNN 模块可以加载预训练模型)。
  6. 机器学习模块 cv::ml:支持向量机 (SVM)、K最近邻 (KNN) 等。
  7. 相机标定与3D重建calib3d 模块。
  8. 探索 OpenCV 的 contrib 模块:包含许多实验性或较新的功能。

重要资源:

实践是学习编程的最佳方式。尝试修改示例代码,用自己的图像和视频进行实验,并挑战一些小的计算机视觉项目。

祝你在计算机视觉的探索之旅中一切顺利!🚀


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值