OpenCV4 C++环境搭建与图像处理入门实战指南

1. 项目概述:从零搭建你的第一个OpenCV4 C++视觉项目

如果你刚接触计算机视觉,或者已经用Python玩过OpenCV但想深入C++底层,这个系列就是为你准备的。我做了十多年工业视觉和嵌入式开发,深知很多教程一上来就扔一堆代码,却不讲清楚“为什么”要这么做。今天,我们就从最基础的“项目搭建”开始,我会带你用C++和OpenCV4,从环境配置到第一个可运行的视觉程序,把每一步的原理和踩过的坑都讲透。

计算机视觉听起来高大上,但核心就是让计算机“看懂”图像。OpenCV作为行业事实标准,提供了从图像处理到深度学习的一整套工具。用C++写OpenCV项目,尤其是在嵌入式、高性能或跨平台场景下,是很多一线项目的标配。这个系列的第一篇,目标很明确:帮你搭建一个坚实、可复现的C++开发环境,并写出第一个能读图、显示、处理图像的程序。别小看这一步,环境配置和基础框架的坑,足以劝退一半的新手。

2. 环境搭建与工具链选择:为什么选它们?

2.1 操作系统与编译器:Windows、Linux还是macOS?

首先得决定在哪开发。我的建议是: 优先考虑你的部署环境

  • Linux (Ubuntu/Debian) :这是计算机视觉开发的“主场”。库依赖管理方便(apt-get),社区支持好,很多算法库原生为Linux优化。如果你做机器人、自动驾驶或服务器端应用,无脑选Ubuntu。我会以Ubuntu 20.04/22.04 LTS为例,因为它足够稳定,生态也成熟。
  • Windows :如果你的团队或客户环境主要是Windows,或者你需要用Visual Studio的强大调试工具,那就选它。注意,在Windows上配置OpenCV的C++环境稍显繁琐,需要自己编译或找预编译包。
  • macOS :开发体验不错,但某些工业相机驱动或特定硬件加速库可能支持不如前两者。用Homebrew管理依赖也很方便。

我的选择与理由 :这个系列我会以 Ubuntu 22.04 为主要环境进行讲解。原因有三:1) 开源生态完整;2) 编译和依赖问题最少;3) 便于后续引入CUDA等加速库。但关键步骤我会补充Windows (Visual Studio 2022) 下的差异点。

2.2 安装OpenCV4:源码编译才是王道

很多人图省事,直接用 apt-get install libopencv-dev 。对于快速验证可以,但对于严肃项目,我 强烈建议从源码编译 。理由如下:

  1. 可控性 :可以精确选择需要的模块(如不装GPU模块以减小体积)。
  2. 优化 :可以针对你的CPU指令集(如AVX2)进行编译优化,提升性能。
  3. 调试 :可以编译Debug版本,方便打断点跟踪OpenCV内部逻辑。
  4. 版本 :apt仓库的版本往往滞后,源码编译总能用到最新稳定版。

实操步骤(Ubuntu)

# 1. 安装依赖库(这些是OpenCV编译和基础功能所必需的)
sudo apt update
sudo apt install -y build-essential cmake git pkg-config
sudo apt install -y libjpeg-dev libtiff-dev libpng-dev libavcodec-dev libavformat-dev libswscale-dev
sudo apt install -y libgtk-3-dev libcanberra-gtk3-dev
sudo apt install -y libxvidcore-dev libx264-dev
sudo apt install -y python3-dev python3-numpy
sudo apt install -y libtbb2 libtbb-dev libdc1394-22-dev
sudo apt install -y libv4l-dev v4l-utils
sudo apt install -y libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev
sudo apt install -y libopenblas-dev libatlas-base-dev libblas-dev
sudo apt install -y liblapack-dev liblapacke-dev libeigen3-dev
sudo apt install -y libhdf5-dev libprotobuf-dev protobuf-compiler
sudo apt install -y libgoogle-glog-dev libgflags-dev

# 2. 下载OpenCV4源码(以4.8.0为例,可替换为最新稳定版)
cd ~
git clone https://github.com/opencv/opencv.git
cd opencv
git checkout 4.8.0
# 如果需要OpenCV贡献库(包含SIFT、FaceDetector等额外算法)
cd ~
git clone https://github.com/opencv/opencv_contrib.git
cd opencv_contrib
git checkout 4.8.0

# 3. 使用CMake配置编译选项
cd ~/opencv
mkdir build && cd build
# 关键配置项解析:
# -D CMAKE_BUILD_TYPE=RELEASE:发布模式,优化性能。调试时改为DEBUG。
# -D CMAKE_INSTALL_PREFIX=/usr/local:安装路径,通常放这里。
# -D OPENCV_EXTRA_MODULES_PATH:指定贡献模块路径,如果你需要那些额外算法。
# -D WITH_CUDA=OFF:如果你有NVIDIA GPU并需要CUDA加速,改为ON并设置ARCH。
# -D BUILD_EXAMPLES=OFF:不编译例子,节省时间。
# -D BUILD_opencv_world=ON:将所有库打包成一个.so/.dll,链接时方便,但文件大。
cmake -D CMAKE_BUILD_TYPE=RELEASE \
      -D CMAKE_INSTALL_PREFIX=/usr/local \
      -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \
      -D WITH_CUDA=OFF \
      -D BUILD_EXAMPLES=OFF \
      -D BUILD_opencv_world=ON \
      ..

# 4. 编译并安装(-j$(nproc) 使用所有CPU核心加速编译)
make -j$(nproc)
sudo make install
sudo ldconfig # 更新动态链接库缓存

注意 :编译过程可能持续30分钟到数小时,取决于你的机器性能。如果中途报错,大概率是某个依赖没装全,根据错误信息用 apt search apt install 补全即可。

Windows下的关键差异

  1. 需要先安装 Visual Studio 2022 (社区版即可),并勾选“使用C++的桌面开发”。
  2. 安装 CMake GUI 工具。
  3. 用CMake GUI指定源码路径和构建路径,点击“Configure”,选择“Visual Studio 17 2022”和“x64”,然后点击“Generate”。
  4. 在构建路径下打开生成的 OpenCV.sln ,在VS里选择 Release|x64 ,然后“生成”->“生成解决方案”,最后在“CMakeTargets”文件夹下右键“INSTALL”->“仅用于项目”->“仅生成INSTALL”。

2.3 IDE与构建系统:CMake是唯一推荐

对于C++项目,构建系统能帮你管理编译、链接、依赖,是项目可维护性的基石。

  • 纯命令行 (g++/cl.exe) :适合微型单文件测试,项目稍大就难以管理。
  • Visual Studio 项目文件 (.vcxproj) :仅限Windows,跨平台协作困难。
  • CMake 行业标准 ,跨平台(Windows/Linux/macOS),语法相对清晰,与OpenCV自身构建系统一致。

为什么是CMake? 它用一份 CMakeLists.txt 文件,就能生成对应平台的构建文件(Linux的Makefile,Windows的VS工程,macOS的Xcode工程)。你的队友用什么系统都能一键编译。

一个最基础的、用于本项目的 CMakeLists.txt 文件如下:

cmake_minimum_required(VERSION 3.10)
project(MyFirstCVProject)

# 设置C++标准(OpenCV4需要C++11以上,建议用C++14/17)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 寻找OpenCV包, REQUIRED表示找不到就报错
find_package(OpenCV REQUIRED)

# 包含OpenCV的头文件目录
include_directories(${OpenCV_INCLUDE_DIRS})

# 添加你的可执行文件,并链接OpenCV库
add_executable(visual_demo main.cpp)
target_link_libraries(visual_demo ${OpenCV_LIBS})

把这个文件放在你的项目根目录,然后在同一目录下执行:

mkdir build && cd build
cmake ..
make

就会生成可执行文件 visual_demo

2.4 验证安装:第一个“Hello, OpenCV!”程序

创建一个 main.cpp 文件,写入以下代码:

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

int main() {
    // 1. 打印OpenCV版本,验证链接是否正确
    std::cout << "OpenCV version: " << CV_VERSION << std::endl;

    // 2. 创建一个简单的黑色图像
    cv::Mat image(300, 600, CV_8UC3, cv::Scalar(0, 0, 0));

    // 3. 在图像上绘制文字
    std::string text = "Hello, OpenCV4 with C++!";
    int fontFace = cv::FONT_HERSHEY_SIMPLEX;
    double fontScale = 1.0;
    int thickness = 2;
    cv::Size textSize = cv::getTextSize(text, fontFace, fontScale, thickness, nullptr);

    // 计算文字位置使其居中
    cv::Point textOrg((image.cols - textSize.width) / 2, (image.rows + textSize.height) / 2);
    cv::putText(image, text, textOrg, fontFace, fontScale, cv::Scalar(0, 255, 0), thickness);

    // 4. 显示图像
    cv::imshow("First OpenCV Window", image);

    // 5. 等待按键,否则窗口会一闪而过
    std::cout << "Press any key in the window to exit..." << std::endl;
    cv::waitKey(0);

    return 0;
}

在项目 build 目录下编译并运行:

cd build
cmake .. # 只需第一次运行或CMakeLists.txt改变时运行
make
./visual_demo

如果弹出一个绿色文字的窗口,恭喜你,环境搭建成功!

3. 核心代码结构解析:不只是“Hello World”

上面的验证程序虽然简单,但已经包含了OpenCV C++程序的几个核心要素。我们来深入拆解:

3.1 cv::Mat :图像的基石

cv::Mat 是OpenCV中存储和操作图像(乃至矩阵)的 绝对核心类 。理解它,就理解了OpenCV的一半。

cv::Mat image(300, 600, CV_8UC3, cv::Scalar(0, 0, 0));

这行代码创建了一个Mat对象:

  • 300 :图像高度(行数)。
  • 600 :图像宽度(列数)。
  • CV_8UC3 :这是 数据类型和通道数 。这是最容易混淆的地方。
    • CV_ :前缀。
    • 8U :深度。 8 表示8位, U 表示无符号(unsigned)。还有 S (有符号)、 F (浮点)。例如 CV_32F 是32位浮点数。
    • C3 :通道数。 3 表示3通道,即常见的BGR彩色图像(注意OpenCV默认是BGR顺序,不是RGB!)。 C1 表示单通道(灰度图)。
  • cv::Scalar(0, 0, 0) :初始化值。对于 CV_8UC3 ,Scalar的三个值分别对应B、G、R通道,这里都是0,所以是纯黑色。

重要特性

  • 内存管理 cv::Mat 使用引用计数,类似智能指针。当你 image2 = image1; 时,不会发生深拷贝,只是增加引用计数。修改 image2 会影响 image1 !如果需要真正的拷贝,必须用 image1.copyTo(image2); cv::Mat image2 = image1.clone();
  • 连续存储 :大多数情况下,Mat的数据在内存中是连续的,可以用 image.isContinuous() 检查,用 image.ptr<uchar>(row) 快速访问行指针。

3.2 图像IO:读、写、显示

  • 读取图像 cv::imread("path/to/image.jpg", cv::IMREAD_COLOR);
    • 第二个参数是加载标志。 IMREAD_COLOR 强制转为3通道BGR, IMREAD_GRAYSCALE 转为灰度, IMREAD_UNCHANGED 保留原样(包括Alpha通道)。 务必检查返回值 if(image.empty()) { std::cerr << "Could not open image!" << std::endl; return -1; }
  • 显示图像 cv::imshow("Window Title", image);
    • 窗口标题必须唯一。它会自动根据图像大小创建窗口。
    • cv::waitKey(0); 必须的 ,它处理GUI事件循环。参数是等待毫秒数,0表示无限等待直到有按键。即使你不显示图像,在某些后端下也需要调用它来释放GUI资源。
  • 保存图像 cv::imwrite("output.png", image);
    • 格式由文件后缀决定。可以指定质量参数(如对于JPEG)。

3.3 基础绘图与文字

cv::putText 只是绘图API之一。OpenCV提供了丰富的绘图函数,在调试和可视化时极其有用:

  • cv::circle(img, center, radius, color, thickness) :画圆。
  • cv::rectangle(img, pt1, pt2, color, thickness) :画矩形。
  • cv::line(img, pt1, pt2, color, thickness) :画线。
  • cv::ellipse , cv::polylines 等。

一个实用技巧 :在循环中绘制检测框或关键点时,可以创建原图的一个拷贝来绘制,避免污染原始数据。

cv::Mat displayImage = image.clone(); // 创建副本用于显示
cv::rectangle(displayImage, cv::Rect(100, 100, 200, 150), cv::Scalar(0, 0, 255), 2);
cv::imshow("Detection", displayImage);

4. 第一个完整的图像处理Demo:灰度化、模糊与边缘检测

现在,我们写一个稍复杂的程序,它完成一个经典的图像处理流水线:读取图片 -> 转灰度 -> 高斯模糊 -> Canny边缘检测 -> 显示结果。

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

int main(int argc, char** argv) {
    // 1. 处理命令行参数
    if (argc != 2) {
        std::cerr << "Usage: " << argv[0] << " <Image_Path>" << std::endl;
        return -1;
    }

    // 2. 读取图像
    cv::Mat originalImage = cv::imread(argv[1], cv::IMREAD_COLOR);
    if (originalImage.empty()) {
        std::cerr << "Error: Could not load image '" << argv[1] << "'" << std::endl;
        return -1;
    }
    std::cout << "Image loaded. Size: " << originalImage.cols << "x" << originalImage.rows
              << ", Channels: " << originalImage.channels() << std::endl;

    // 3. 转换为灰度图
    cv::Mat grayImage;
    cv::cvtColor(originalImage, grayImage, cv::COLOR_BGR2GRAY);
    std::cout << "Converted to grayscale." << std::endl;

    // 4. 应用高斯模糊去噪
    cv::Mat blurredImage;
    int kernelSize = 5; // 高斯核大小,必须是正奇数
    double sigmaX = 1.5; // X方向标准差,0表示根据核大小自动计算
    cv::GaussianBlur(grayImage, blurredImage, cv::Size(kernelSize, kernelSize), sigmaX);
    std::cout << "Applied Gaussian blur with kernel size " << kernelSize << "." << std::endl;

    // 5. Canny边缘检测
    cv::Mat edgeImage;
    double lowThreshold = 50;  // 低阈值
    double highThreshold = 150; // 高阈值,一般为低阈值的2-3倍
    int apertureSize = 3; // Sobel算子孔径大小,必须是1, 3, 5, 7
    cv::Canny(blurredImage, edgeImage, lowThreshold, highThreshold, apertureSize);
    std::cout << "Canny edge detection applied." << std::endl;

    // 6. 显示所有结果
    cv::imshow("1. Original Color Image", originalImage);
    cv::imshow("2. Grayscale Image", grayImage);
    cv::imshow("3. After Gaussian Blur", blurredImage);
    cv::imshow("4. Canny Edges", edgeImage);

    // 7. 保存结果
    cv::imwrite("gray_image.jpg", grayImage);
    cv::imwrite("edges.jpg", edgeImage);
    std::cout << "Intermediate results saved as 'gray_image.jpg' and 'edges.jpg'." << std::endl;

    // 8. 等待退出
    std::cout << "Press any key to exit..." << std::endl;
    cv::waitKey(0);

    return 0;
}

编译与运行

cd build
make
./visual_demo /path/to/your/photo.jpg

4.1 关键步骤原理解析

  1. 灰度化 ( cv::cvtColor ) :将BGR三通道图像转换为单通道灰度图。常用公式是 Gray = 0.299*R + 0.587*G + 0.114*B (亮度公式)。OpenCV内部会优化这个计算。

  2. 高斯模糊 ( cv::GaussianBlur ) :一种线性平滑滤波器,用于消除图像中的高频噪声(如椒盐噪声)。它用一个高斯函数生成的权值矩阵(卷积核)去扫描图像,每个像素的新值是其邻域像素的加权平均。 sigmaX 控制权重分布,值越大图像越模糊。 为什么先模糊再找边缘? 因为原始图像可能有噪声,噪声点也会产生高强度梯度,被误判为边缘。先平滑可以抑制噪声。

  3. Canny边缘检测 ( cv::Canny ) :经典的边缘检测算法,包含多步:

    • 计算梯度 :用Sobel算子计算图像在X和Y方向的梯度幅值和方向。
    • 非极大值抑制 :沿着梯度方向,只保留梯度幅值最大的点,细化边缘。
    • 双阈值滞后连接 :用 lowThreshold highThreshold 过滤。高于高阈值的为强边缘,保留;低于低阈值的丢弃;在两者之间的为弱边缘,只有当它们连接到强边缘时才保留。这保证了边缘的连续性和抗噪性。

4.2 参数调优与常见问题

  • 高斯核大小 :必须是正奇数(如3,5,7)。越大越模糊,计算越慢。通常5或7是个不错的起点。
  • Canny阈值 :这是 最需要调参 的地方。没有万能值。
    • 太高 :只检测出最明显的边缘,可能断裂。
    • 太低 :检测出太多边缘,包括噪声。
    • 调试技巧 :可以设计一个滑动条实时调整,或者用大津法(Otsu‘s Method)自动计算阈值。对于 cv::Canny ,可以先用 cv::threshold cv::adaptiveThreshold 观察合适的阈值范围。
  • 图像路径问题 :如果传入中文路径或带空格的路径, imread 可能会失败。在Windows上尤其要注意。可以用 cv::String std::string 正确构造路径。

5. 项目结构规划与代码组织

一个可维护的视觉项目,不能把所有代码都堆在 main.cpp 里。我推荐这样的目录结构(在项目根目录下):

MyFirstCVProject/
├── CMakeLists.txt              # 项目主CMake文件
├── main.cpp                    # 程序入口
├── include/                    # 自己写的头文件
│   └── ImageProcessor.hpp
├── src/                        # 自己写的源文件
│   ├── ImageProcessor.cpp
│   └── utils.cpp
├── data/                       # 测试数据、图片、模型
│   └── test_image.jpg
├── build/                      # 编译输出目录(.gitignore忽略)
├── scripts/                    # 辅助脚本(如一键编译、清理)
└── README.md                   # 项目说明

对应的 CMakeLists.txt 需要升级:

cmake_minimum_required(VERSION 3.10)
project(MyFirstCVProject VERSION 1.0.0)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 查找OpenCV
find_package(OpenCV REQUIRED)

# 包含头文件目录:自己的include和OpenCV的
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${OpenCV_INCLUDE_DIRS})

# 添加可执行文件,并链接所有源文件
add_executable(visual_demo 
    main.cpp
    src/ImageProcessor.cpp
    src/utils.cpp
)

# 链接OpenCV库
target_link_libraries(visual_demo ${OpenCV_LIBS})

# 可选:设置输出目录
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)

这样,你就可以把图像处理的逻辑(比如灰度化、模糊、Canny)封装到 ImageProcessor 类中, main.cpp 只负责流程控制。这是迈向大型项目的第一步。

6. 调试与性能分析初步

6.1 使用GDB/LLDB调试

在Linux/macOS下,编译Debug版本并调试:

# 修改CMakeLists.txt,或在cmake命令中指定
# -D CMAKE_BUILD_TYPE=Debug
cd build
cmake -D CMAKE_BUILD_TYPE=Debug ..
make
gdb ./visual_demo
# 在gdb中:break main, run, next, print variable_name

在Windows下,直接用Visual Studio的调试器,设置断点、监视变量非常方便。

6.2 简单的性能测量

OpenCV提供了 cv::TickMeter 来方便地测量代码段耗时。

#include <opencv2/core/utility.hpp> // 包含TickMeter

cv::TickMeter tm;
tm.start();
// ... 你的耗时操作,比如循环处理1000次模糊
for(int i = 0; i < 1000; ++i) {
    cv::GaussianBlur(src, dst, cv::Size(5,5), 1.5);
}
tm.stop();
std::cout << "Elapsed time: " << tm.getTimeMilli() << " ms" << std::endl;

6.3 内存泄漏检查

虽然 cv::Mat 有引用计数管理,但如果你用 new 创建了 cv::Mat* ,或者使用了 cv::Mat::create 后没有正确释放,也可能泄漏。对于简单项目,确保遵循RAII原则,尽量使用栈对象而非堆对象。对于复杂项目,可以使用Valgrind(Linux)或Visual Studio Diagnostic Tools(Windows)进行检测。

7. 常见问题与排查技巧实录

这里记录了我早期和带新人时最常遇到的坑:

问题1:编译时找不到 opencv2/opencv.hpp 头文件。

  • 原因 :CMake没有正确找到OpenCV,或者 find_package 失败。
  • 排查
    1. 检查OpenCV是否安装成功: pkg-config --modversion opencv4 (Linux) 或查看 /usr/local/include/opencv4 (Linux) / C:\opencv\build\include (Windows) 是否存在。
    2. 检查CMake输出,看是否找到了OpenCV以及路径是否正确。
    3. CMakeLists.txt 中, find_package 后添加 message(STATUS "OpenCV lib status: ${OpenCV_LIBS}") 打印信息。

问题2:运行时错误: error while loading shared libraries: libopencv_core.so.408: cannot open shared object file

  • 原因 :动态链接库路径没被系统识别。
  • 解决(Linux)
    • 永久方案:将OpenCV的lib路径(如 /usr/local/lib )加入 /etc/ld.so.conf 或创建 .conf 文件到 /etc/ld.so.conf.d/ ,然后执行 sudo ldconfig
    • 临时方案:运行程序前设置 export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
  • 解决(Windows) :将OpenCV的 bin 目录(包含.dll文件)添加到系统的 PATH 环境变量中。

问题3:图像显示窗口一闪而过,或者 imshow 后没有显示。

  • 原因 :缺少 cv::waitKey() waitKey 不仅是等待按键,它还是OpenCV HighGUI模块处理窗口事件(刷新、重绘)的必要调用。即使你不关心按键,也需要一个短暂的 waitKey(1) 放在循环里,或者用 waitKey(0) 阻塞。

问题4:处理视频或摄像头时,程序占用CPU 100%,且很卡顿。

  • 原因 :在读取帧的循环里没有适当的延迟,或者 imshow 开销太大。
  • 解决
    cv::VideoCapture cap(0); // 打开摄像头
    while(true) {
        cv::Mat frame;
        cap >> frame;
        if(frame.empty()) break;
        // ... 处理frame ...
        cv::imshow("Video", frame);
        char c = cv::waitKey(30); // 等待约30ms,对应~33FPS,同时处理按键
        if(c == 27) break; // ESC退出
    }
    
    • 如果处理很耗时,导致实际FPS远低于摄像头帧率,考虑将 采集线程 处理线程 分离。

问题5: cv::Mat 赋值后,修改副本影响了原图。

  • 原因 :忘记了 cv::Mat 的浅拷贝特性。
  • 解决 :需要深拷贝时,务必使用 .clone() .copyTo()
    cv::Mat img1 = cv::imread("test.jpg");
    cv::Mat img2 = img1; // 浅拷贝,img2和img1共享数据!
    cv::Mat img3 = img1.clone(); // 深拷贝,独立数据
    img2.setTo(cv::Scalar(0)); // 这会清空img1和img2!
    // img3不受影响
    

问题6:在树莓派等嵌入式设备上编译OpenCV速度极慢,且容易内存不足。

  • 解决
    1. 增加交换空间: sudo dphys-swapfile swapoff && sudo dphys-swapfile set-swap-size 2048 && sudo dphys-swapfile setup && sudo dphys-swapfile swapon (将交换文件设为2GB)。
    2. 只编译最需要的模块:在CMake时,禁用不需要的 BUILD_opencv_* 选项,如 -D BUILD_opencv_python=OFF -D BUILD_opencv_java=OFF -D BUILD_opencv_dnn=OFF 等。
    3. 使用 make -j2 make -j1 减少并行编译任务,避免内存爆掉。

8. 下一步做什么?项目扩展思路

第一个项目跑通后,你可以沿着这些方向深入:

  1. 处理视频流 :将 cv::imread 换成 cv::VideoCapture ,参数可以是摄像头索引(如0)或视频文件路径。
  2. 加入交互 :使用 cv::createTrackbar 创建滑动条,实时调整Canny阈值、模糊强度等参数,直观感受算法效果。
  3. 尝试更多基础算法
    • 阈值分割 cv::threshold , cv::adaptiveThreshold
    • 形态学操作 cv::erode , cv::dilate , cv::morphologyEx (用于去噪、连接断边)。
    • 轮廓查找 cv::findContours ,这是物体分割和形状分析的基础。
  4. 为下一篇做准备 :下一篇我们将深入图像预处理、分割和特征提取,最终搭建一个简单的物体分类器。你可以尝试用 cv::findContours 找出当前边缘图像中的所有轮廓,并计算它们的面积、周长、外接矩形,这是从边缘到“物体”的关键一步。

环境搭建和第一个程序是万里长征的第一步,但也是最容易让人放弃的一步。一旦跨过去,后面就是广阔的计算机视觉世界。记住,遇到问题多查OpenCV官方文档(https://docs.opencv.org/4.x/),多调试,多动手试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值