C++ 机器视觉入门:从零搭建 AOI 开发环境(OpenCV + CMake)

引言

很多刚接触机器视觉的同学,一上来就被"装环境"这件事劝退了:装完 OpenCV 编译报错、链接报错、跑起来又闪退。其实这些问题大多源于对工程组织方式不熟悉,而不是代码本身难。

本文面向有 C++ 基础、但刚接触机器视觉和 OpenCV 的读者,解决一个具体问题:如何从零搭建一套可以复用的 AOI(自动光学检测)开发环境。读完本文你能学到三件事:一是理解 AOI 是什么、用在哪里;二是明白为什么工业界选 C++ + OpenCV;三是亲手完成"安装环境 → 用 CMake 组织工程 → 编译运行第一个读图程序"的完整闭环,并避开最常见的几个坑。

什么是 AOI

AOI(Automated Optical Inspection,自动光学检测),是用工业相机拍摄被测物体,再用图像处理算法自动判断产品是否有缺陷的技术。它代替人眼完成重复、高速、客观的质量检查,是智能制造里的"电子质检员"。

典型的应用场景包括:

场景 检测内容
PCB 板检测 焊点虚焊、连锡、元件缺失、极性反装
SMT 贴片 贴片偏移、错料、立碑、少件
显示面板 亮点、暗点、划痕、Mura 污渍
外观检测 划伤、毛刺、脏污、尺寸测量

一条 AOI 流水线大致分为四步:打光与成像 → 图像预处理 → 特征提取与判定 → 结果输出。其中图像处理部分,绝大多数项目都离不开 OpenCV。所以学 AOI,第一步不是急着写检测算法,而是先把 OpenCV 这套开发环境搭稳。

为什么选择 OpenCV + C++

OpenCV 是目前最流行的开源计算机视觉库,覆盖图像读写、滤波、形态学、轮廓分析、特征匹配、相机标定等 AOI 常用的几乎全部基础能力,且跨平台、有活跃社区。

而工业落地更偏爱 C++,原因很实在:

  • 性能:AOI 往往要求每秒检测多件产品,C++ 贴近硬件、没有 GC 停顿,配合 OpenCV 的 SIMD 优化能榨干 CPU。
  • 可控性:内存、线程、时延都可精细管理,满足产线实时性要求。
  • 部署:C++ 程序可编译为独立可执行文件或动态库,方便集成到产线上位机软件。

一句话总结:用 Python 做原型验证很快,但真正上产线的高性能检测,通常还是 C++。 本文用 OpenCV 4.x 作为示例。

环境安装:Windows 与 Ubuntu

Windows 下安装

最省心的方式是使用官方预编译包:

  1. 到 OpenCV 官网下载 Windows 版 opencv-4.x.x-windows.exe,解压到例如 D:\opencv。
  2. 解压后目录结构里有 build\x64\vc16\bin(动态库 .dll)和 build\include(头文件)。
  3. 把 D:\opencv\build\x64\vc16\bin 加入系统环境变量 PATH,否则运行时找不到 opencv_world4xx.dll。
  4. 用 CMake 配置工程时,指定 OpenCV_DIR 指向解压目录里的 build 文件夹即可。

建议配一个本地安装的 Visual Studio(社区版即可)作为编译器,CMake 用它生成解决方案。

Ubuntu 下安装

Ubuntu 可以用 apt 一键安装,也可以源码编译(需要定制模块时再考虑)。入门推荐 apt:

复制代码
sudo apt update
sudo apt install -y libopencv-dev cmake g++ pkg-config

安装完成后用 pkg-config 验证:

复制代码
pkg-config --modversion opencv4

能打印出 4.x.x 就说明安装成功。Ubuntu 官方源里的 libopencv-dev 通常自带 opencv4.pc,供 pkg-config 查询编译参数。

用 CMake 组织工程

CMake 是跨平台的构建工具,作用是"用一份配置生成各平台的构建文件":Windows 上生成 VS 工程,Linux 上生成 Makefile。工业项目几乎都用它,所以第一步就养成好习惯。

一个最小工程长这样:

复制代码
aoi-demo/
├── CMakeLists.txt
├── main.cpp
└── sample.jpg   # 任意一张测试图片

CMakeLists.txt 内容如下:

cpp 复制代码
cmake_minimum_required(VERSION 3.10)

# 项目名
project(aoi_hello)

# OpenCV 4 要求至少 C++11,这里统一用 C++11
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 查找 OpenCV(默认会找系统里已安装的 OpenCV)
find_package(OpenCV REQUIRED)

# 生成可执行文件 app,源码是 main.cpp
add_executable(app main.cpp)

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

核心就三件事:find_package(OpenCV REQUIRED) 找到 OpenCV,add_executable 声明目标,target_link_libraries 完成链接。

第一个程序:读取并显示一张图片

main.cpp 完整代码如下:

cpp 复制代码
#include <opencv2/opencv.hpp>   // OpenCV 主头文件
#include <iostream>

using namespace cv;     // 常用:Mat、imread 等都在 cv 命名空间
using namespace std;

int main(int argc, char** argv)
{
    // 1. 读取图片:IMREAD_COLOR 表示按 3 通道彩色图读取
    //    路径请改成你自己电脑上的图片路径
    Mat img = imread("sample.jpg", IMREAD_COLOR);

    // 2. 判断是否读取成功:empty() 为 true 说明没读到
    if (img.empty())
    {
        cout << "图片读取失败,请检查路径是否正确!" << endl;
        return -1;
    }

    // 3. 打印图片基本信息(宽 x 高、通道数)
    cout << "图片尺寸: " << img.cols << " x " << img.rows << endl;
    cout << "通道数: " << img.channels() << endl;

    // 4. 显示图片,窗口标题为 "AOI 第一张图"
    imshow("AOI 第一张图", img);

    // 5. 等待按键:参数 0 表示无限等待,直到用户按下任意键
    //    没有这一句,窗口会一闪而过甚至直接退出
    waitKey(0);

    return 0;
}

编译运行

Linux / Ubuntu(直接用 g++ 编译):

复制代码
g++ main.cpp -o app $(pkg-config --cflags --libs opencv4)
./app

Linux / Ubuntu(用 CMake,推荐):

复制代码
mkdir build && cd build
cmake ..
make
./app

Windows(用 CMake + VS):

复制代码
mkdir build
cd build
cmake .. -G "Visual Studio 17 2022"
# 打开生成的 .sln 编译,或在命令行执行 cmake --build . --config Release

逐段讲解

  • Mat img = imread(...) :Mat 是 OpenCV 里表示图像的核心类,本质是一块二维像素矩阵。imread 负责把磁盘图片解码成 Mat。
  • img.empty() :这是必须写的防御性检查 。读图失败时 img 是空的,若直接拿去显示或计算会崩溃。失败常见原因是路径不对或文件不存在。
  • imshow 与 waitKey :imshow 只是"把图画到窗口",真正让窗口刷新、响应鼠标键盘的是 waitKey。它同时承担"等待按键"和"事件循环"两个职责,缺一不可。
  • IMREAD_COLOR :读图模式标志。另有 IMREAD_GRAYSCALE(灰度,用于大多数检测算法)、IMREAD_UNCHANGED(保留透明通道)等,AOI 里灰度图用得非常多。

运行效果

程序正确运行后,会弹出标题为"AOI 第一张图"的窗口,展示你的测试图片;控制台打印类似:

复制代码
图片尺寸: 640 x 480
通道数: 3

按键盘任意键,窗口关闭,程序正常退出(返回码 0)。如果打印"图片读取失败",说明图片没找到,按下一节的排查思路检查即可。

常见坑与注意事项

  1. 找不到头文件 opencv2/opencv.hpp :g++ 编译时没加 pkg-config --cflags,或 CMake 里没执行 find_package。本质是编译器不知道头文件在哪,补上 include 路径即可。
  2. undefined reference to cv::... :这是典型的链接错误 ,说明编译通过了但没链 OpenCV 库。检查 pkg-config --libs 是否带上,或 CMake 是否写了 target_link_libraries。
  3. imshow 窗口一闪而过 / 闪退 :几乎都是漏写 waitKey。没有它,程序执行完直接返回,窗口来不及显示。
  4. 图片路径含中文 :OpenCV 的 imread 在部分平台(尤其 Windows 默认编码下)对中文路径支持不好,可能读出来是空。优先把图片放到工程目录、用英文文件名 ;确需中文路径时再考虑 imdecode 配合 ifstream 读取的方案。
  5. Windows 下报找不到 opencv_world4xx.dll :运行期动态库不在 PATH 里,把 bin 目录加进环境变量即可。
  6. 图片路径用相对路径却读不到:相对路径的基准是"程序运行时的工作目录",不是源码目录。IDE 里运行时注意设置工作目录,或改用绝对路径排查。

小结

本文完成了 AOI 开发的第一块地基:理解了 AOI 是什么、为什么选 C++ + OpenCV,并且在 Windows / Ubuntu 上装好环境,用 CMake 组织了一个最小工程,跑通了"读图 → 判空 → 显示 → 等待按键"的完整流程,还梳理了六个高频坑。

这一步看起来简单,却是后续所有检测算法的前提。环境稳了,接下来无论是灰度化、二值化、形态学去噪,还是轮廓提取与缺陷判定,都能在这套骨架上顺畅展开。建议你现在就动手:建好工程、放一张测试图、把程序跑起来,遇到报错先对照"常见坑"逐一排查------亲手排掉一个坑,比看十遍教程都管用。

相关推荐
誰能久伴不乏1 小时前
【无标题】
c++·qt·机器人
zhangx1234_1 小时前
javaEE 多线程4
java·开发语言
大陈子编程1 小时前
C++ 背包九讲:从入门到精通的动态规划专题
开发语言·c++·动态规划
qq_401700411 小时前
Qt 组播(Multicast)实战详解
开发语言·qt
Sapphire~2 小时前
odoo-095 视图的重写规则(全部重写还是部分改写)
开发语言·javascript·ecmascript
利威尔xu2 小时前
Go GMP 调度器 10 个高频追问:3 个线上故障让 P99 从 80ms 飙到 2s、10 万 goroutine 泄漏
开发语言·后端·面试·性能优化·golang
中电金信2 小时前
从业务调优到分层缓存:DeepSeek V4 Flash的PPU实践
java·开发语言
梦影_2 小时前
MySQL进阶教程(二)—— 储存过程与触发器(下)
开发语言·数据库·后端·sql·mysql·oracle·数据库开发
lg_cool_2 小时前
Python 代码打包
开发语言·python