简介:OpenCV 3.2 是开源计算机视觉库的一个经典版本,面向计算机视觉、机器学习与人工智能方向的开发者及学习者,可用于图像处理、特征检测、目标识别、视频分析等实际项目。资源包共178个文件,以116个hpp头文件与57个h头文件为主,另含3个dll动态库和2个lib导入库,压缩包约25.19MB,属于可直接调用的库文件集合,便于在C++工程中集成与二次开发。内容覆盖基本图像操作、滤波去噪、SIFT/SURF/ORB特征检测、Haar级联与HOG行人检测、GrabCut与Watershed图像分割、视频帧捕获与运动分析,以及DNN模块加载预训练模型、aruco标记识别和Calib3d相机标定等核心模块。已有751人学习下载,适合希望系统掌握OpenCV 3.2接口、快速搭建视觉实验环境的读者参考使用。
1. 从一次编译翻车说起:为什么现在还有人装 OpenCV 3.2
前阵子帮一个做图像处理 Demo 的团队复现旧项目,代码里写死了cv::xfeatures2d::SIFT的调用,跑在 OpenCV 4.x 上直接抛异常。翻回去看依赖清单,人家当年锁的就是 OpenCV 3.2。这事在计算机视觉圈子里其实不罕见——很多老论文的参考实现、工业视觉的存量代码、某些 SDK 的示例工程,都还挂在 3.2 这个版本上。OpenCV 3.2 发布于 2016 年底,是 3.x 系列里相对稳定的一版,SIFT/SURF 还在xfeatures2d里、cv2.findContours的返回值还是三元素、CascadeClassifier的 API 也没改。你要是拿 4.x 的教程去套,轻则编译报错,重则运行时段错误,排查起来相当玄学。这篇笔记就是把我自己装 OpenCV 3.2 的完整过程拆开,从源码编译到环境变量配置,再到装坏了怎么救,一步步写清楚,适合需要复现旧视觉项目、又不想在环境上耗一整天的开发者。
2. 装之前先定版本:源码编译还是包管理,3.2 的依赖清单
2.1 为什么 3.2 基本只能走源码编译
OpenCV 3.2 这个版本,官方预编译包覆盖的系统很有限。Windows 上还能找到对应的.exe自解压包,但 Linux 和 macOS 上,apt、brew这些包管理器里早就滚到 4.x 了,pip install opencv-python==3.2.0.6虽然存在,但那是社区维护的 wheel,Python 版本一高就装不上,而且不带xfeatures2d这些 contrib 模块。所以只要你的项目用到 SIFT、SURF、text模块或者face模块,基本只有一条路:下载源码,自己编译。源码编译的好处是能精确控制 contrib 模块、CUDA 支持、Python 绑定版本;坏处是依赖多、耗时长、报错信息不友好。我一般会先花十分钟把依赖装齐,再开始编译,比边编边补依赖省事得多。
2.2 依赖清单和版本对照
下面这张表是我在 Ubuntu 18.04 和 20.04 上实测过的依赖组合,CentOS 7 也能用,只是包名换成yum的写法。注意 OpenCV 3.2 对 GCC 版本比较敏感,GCC 7 以上编译时会有警告,GCC 9 以上可能直接报错,建议用 GCC 5 或 GCC 7。
| 依赖项 | 作用 | Ubuntu 包名 | 最低版本 |
|---|---|---|---|
| CMake | 构建系统 | cmake | 3.5.1 |
| GCC/G++ | 编译器 | build-essential | 5.4 |
| GTK | 图形界面 | libgtk-3-dev | 3.0 |
| Python | Python 绑定 | python3-dev | 3.5 |
| NumPy | Python 数组支持 | python3-numpy | 1.11 |
| Video I/O | 视频读写 | libavcodec-dev | — |
| JPEG/PNG | 图像编解码 | libjpeg-dev libpng-dev | — |
| TIFF | TIFF 支持 | libtiff-dev | — |
| Eigen | 矩阵运算 | libeigen3-dev | 3.2 |
装依赖的命令我习惯一次性跑完,省得来回确认:
# Ubuntu/Debian 下一次性装齐 OpenCV 3.2 编译依赖 sudo apt-get update sudo apt-get install -y build-essential cmake git pkg-config \ libgtk-3-dev libavcodec-dev libavformat-dev libswscale-dev \ libjpeg-dev libpng-dev libtiff-dev libeigen3-dev \ python3-dev python3-numpy这段命令里,build-essential提供 GCC 和 make,pkg-config帮 CMake 找库路径,libgtk-3-dev是highgui模块显示窗口用的,缺了它imshow会报错。libavcodec-dev这一组是视频读写依赖,不装的话VideoCapture打不开 mp4。Python 那两行是给cv2模块用的,python3-dev提供头文件,python3-numpy提供数组支持。装完可以用gcc --version和cmake --version确认一下版本,GCC 如果高于 9,建议装个gcc-7并切换,否则编译到modules/core时容易卡住。
2.3 源码下载和目录规划
依赖齐了之后,下载 OpenCV 3.2 主仓库和 contrib 仓库。contrib 里放的就是 SIFT、SURF 这些额外模块,不下载的话xfeatures2d根本不存在。我一般会在~/opencv_build下操作,编译产物和源码分开,方便后面清理。
# 建工作目录,下载 3.2 主仓库和 contrib mkdir -p ~/opencv_build && cd ~/opencv_build git clone --branch 3.2.0 https://github.com/opencv/opencv.git git clone --branch 3.2.0 https://github.com/opencv/opencv_contrib.git--branch 3.2.0这个参数很关键,不写的话默认拉 master,那就是 4.x 的代码了。两个仓库的 tag 必须一致,主仓库用 3.2.0,contrib 也得用 3.2.0,版本错配会在 CMake 配置阶段报CMake Error: contrib modules version mismatch。下载完可以cd opencv && git describe --tags确认一下当前 tag 是不是 3.2.0。
3. CMake 配置:参数怎么选,contrib 和 Python 绑定怎么挂
3.1 建 build 目录和基础配置命令
OpenCV 官方推荐 out-of-source 编译,也就是在源码目录外建一个build目录,所有编译产物都放里面,不污染源码树。这一步的 CMake 命令是整个安装过程里参数最多、最容易写错的地方,我先把完整命令贴出来,再逐条解释。
# 在 opencv 源码目录外建 build 目录 cd ~/opencv_build/opencv mkdir build && cd build # CMake 配置,注意 OPENCV_EXTRA_MODULES_PATH 指向 contrib 的 modules cmake -D CMAKE_BUILD_TYPE=RELEASE \ -D CMAKE_INSTALL_PREFIX=/usr/local \ -D OPENCV_EXTRA_MODULES_PATH=~/opencv_build/opencv_contrib/modules \ -D INSTALL_PYTHON_EXAMPLES=ON \ -D INSTALL_C_EXAMPLES=OFF \ -D BUILD_EXAMPLES=OFF \ -D WITH_CUDA=OFF \ -D WITH_GTK=ON \ -D PYTHON3_EXECUTABLE=/usr/bin/python3 \ -D PYTHON3_INCLUDE_DIR=/usr/include/python3.6m \ -D PYTHON3_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.6m.so \ -D PYTHON3_NUMPY_INCLUDE_DIRS=/usr/lib/python3/dist-packages/numpy/core/include \ ..CMAKE_BUILD_TYPE=RELEASE表示开优化,编译出来的库性能好,调试信息少;如果你要跟代码调试,可以改成Debug,但体积会大很多。CMAKE_INSTALL_PREFIX=/usr/local是安装路径,装完libopencv_*.so会进/usr/local/lib,头文件进/usr/local/include。OPENCV_EXTRA_MODULES_PATH必须指向 contrib 仓库下的modules目录,路径写错的话 SIFT 就编不进来。WITH_CUDA=OFF是因为 3.2 对 CUDA 9 以上支持不好,没有 NVIDIA 显卡或者不需要 GPU 加速就关掉,省得编译报错。Python 那几行是显式指定 Python 3 的路径,不写的话 CMake 可能找到 Python 2,导致cv2装到 Python 2 的 site-packages 里。
3.2 参数取舍:哪些该开,哪些该关
CMake 配置阶段会打印一大堆Found和NOT Found,新手容易看花眼。我的经验是重点盯三个地方:Python 绑定有没有找到、contrib 模块有没有加载、GTK 有没有找到。下面这张表是我对几个关键参数的取舍建议。
| 参数 | 建议值 | 原因 |
|---|---|---|
| WITH_CUDA | OFF | 3.2 对高版本 CUDA 兼容差,无 GPU 需求就关 |
| WITH_GTK | ON | 关掉后imshow不可用,调试图像很麻烦 |
| BUILD_opencv_python3 | ON | 默认就是 ON,确认别被覆盖 |
| OPENCV_ENABLE_NONFREE | ON | 要用 SURF 等专利算法必须开 |
| BUILD_TESTS | OFF | 省编译时间,除非你要跑测试用例 |
| BUILD_PERF_TESTS | OFF | 同上,非必要不开 |
OPENCV_ENABLE_NONFREE=ON这个参数容易被忽略,SURF、SIFT 在 3.2 里虽然还在 contrib,但部分算法受专利保护,不开这个开关编译时会跳过。如果你项目里用了 SURF,配置完最好grep -r "NONFREE" CMakeCache.txt确认一下。
3.3 配置阶段的常见报错和应对
CMake 配置阶段最常见的报错是找不到 Python 相关路径,报错信息类似Could NOT find PythonInterp或者Python3_NUMPY_INCLUDE_DIRS为空。这时候先确认python3-dev和python3-numpy装了没有,再用python3 -c "import numpy; print(numpy.get_include())"打印 numpy 头文件路径,手动填到PYTHON3_NUMPY_INCLUDE_DIRS里。另一个常见报错是CMake Error at cmake/OpenCVUtils.cmake:...提示 contrib 版本不匹配,那就是两个仓库 tag 不一致,重新git checkout 3.2.0对齐即可。配置成功后,终端最后会打印Configuring done和Generating done,这时候才能进下一步编译。
4. 编译与安装:make 参数、耗时预估和装完的收尾
4.1 make 的并行参数和内存控制
CMake 配置通过后,build目录下会生成 Makefile,直接make就能编译。但 OpenCV 3.2 的代码量不小,单线程编译在普通机器上要一个多小时,所以一般用-j开并行。并行数不是越大越好,它跟 CPU 核数和内存都相关,我一般取CPU 核数和内存 GB 数 / 2里较小的那个。
# 查看 CPU 核数,决定 -j 参数 nproc # 并行编译,-j4 表示 4 个任务并行,内存 8G 以下建议 -j2 make -j4 # 编译完成后安装到 CMAKE_INSTALL_PREFIX 指定的路径 sudo make install # 刷新动态链接库缓存,让系统找到新装的 .so sudo ldconfigmake -j4里的 4 是并行任务数,如果你机器是 4 核 8G,用-j4比较稳;如果是 2 核 4G 的云主机,建议-j2,否则编译到modules/dnn时容易因为内存不足被 OOM Killer 杀掉,报错信息是c++: internal compiler error: Killed,看起来像编译器崩了,其实是内存不够。sudo make install会把编译好的库和头文件拷到/usr/local,这一步需要 root 权限。sudo ldconfig是刷新动态链接器缓存,不跑的话运行程序时可能报error while loading shared libraries: libopencv_core.so.3.2,因为系统不知道/usr/local/lib下有新库。
4.2 编译耗时的心理预期
不同机器编译 OpenCV 3.2 的耗时差别很大,我整理了一个粗略的对照,方便你判断是不是卡住了。
| 机器配置 | 并行参数 | 大致耗时 |
|---|---|---|
| 2 核 4G 云主机 | -j2 | 60~90 分钟 |
| 4 核 8G 笔记本 | -j4 | 30~45 分钟 |
| 8 核 16G 工作站 | -j8 | 15~25 分钟 |
| 16 核 32G 服务器 | -j16 | 8~15 分钟 |
编译过程中终端会滚动大量[ xx%] Building CXX object ...,只要百分比在涨就没问题。如果卡在某个百分比超过十分钟不动,大概率是某个模块编译卡死,可以 Ctrl+C 中断,进build目录重新make -j2单线程续编,通常能过。
4.3 安装后的目录结构确认
make install跑完后,可以用几条命令确认文件都到位了。库文件应该在/usr/local/lib下,头文件在/usr/local/include/opencv2,Python 的cv2模块在 Python 的 site-packages 里。
# 确认库文件 ls /usr/local/lib/libopencv_core.so* # 确认头文件 ls /usr/local/include/opencv2/core.hpp # 确认 Python 绑定 python3 -c "import cv2; print(cv2.__version__)"如果python3 -c "import cv2"报ModuleNotFoundError,说明 Python 绑定没装到当前 Python 的搜索路径里。可以先find /usr/local -name "cv2*.so"找到文件位置,再把它所在的目录加到PYTHONPATH,或者做个软链接到 site-packages。这一步是新手最容易卡住的地方,下一章会专门讲排查。
5. 避坑与排查:装 OpenCV 3.2 最容易翻车的五个地方
5.1 现象:import cv2 报 ModuleNotFoundError
原因通常是 CMake 配置时 Python 路径没找对,cv2.so被装到了另一个 Python 版本的 site-packages 里,或者根本没生成。解决方法是先find /usr/local -name "cv2*.so"定位文件,如果找到了,用python3 -c "import site; print(site.getsitepackages())"打印当前 Python 的包路径,把cv2.so软链接过去;如果没找到,说明编译时 Python 绑定没开,回build目录重新跑 CMake,加上-D BUILD_opencv_python3=ON再编译。
5.2 现象:运行时报 libopencv_core.so.3.2 找不到
这是动态链接器没刷新缓存。make install之后必须跑sudo ldconfig,它会把/usr/local/lib下的新库注册到系统缓存。如果跑了还报错,检查/etc/ld.so.conf.d/下有没有包含/usr/local/lib的配置文件,没有的话新建一个opencv.conf写入/usr/local/lib,再sudo ldconfig。另外确认LD_LIBRARY_PATH没有把/usr/local/lib排除掉。
5.3 现象:编译到一半报 internal compiler error: Killed
这是内存不足被系统杀进程,不是编译器 bug。OpenCV 3.2 的dnn和stitching模块编译时单个进程可能吃 2G 以上内存,-j开太大就爆了。解决办法是降低并行数,make -j1单线程重编,或者临时加 swap。我一般会在编译前free -h看一眼可用内存,4G 以下直接-j1,别贪快。
5.4 现象:SIFT 创建失败,提示未定义
SIFT 在 3.2 里属于xfeatures2d,需要 contrib 模块,而且部分算法要开OPENCV_ENABLE_NONFREE。如果cv2.xfeatures2d.SIFT_create()报AttributeError,先确认import cv2; print(cv2.__version__)是 3.2.0,再确认hasattr(cv2, 'xfeatures2d')为 True。如果xfeatures2d不存在,就是 contrib 没编进来,回 CMake 检查OPENCV_EXTRA_MODULES_PATH路径是否正确,重新配置编译。
5.5 现象:imshow 报 GTK 相关错误
imshow依赖 GTK,如果 CMake 配置时WITH_GTK=OFF或者系统没装libgtk-3-dev,highgui模块会用不了图形界面,运行时报The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support。解决办法是装libgtk-3-dev,回build目录重新 CMake,确认输出里有GTK+: YES,再重新编译。如果是在无图形界面的服务器上跑,那就别用imshow,改用cv2.imwrite存图再下载查看。
6. 装完怎么验证:三条命令确认 OpenCV 3.2 真的能用
装完不验证,等于没装。我一般会跑三条命令,分别确认版本、contrib 模块和实际图像处理能力。第一条最简单,确认版本号:
python3 -c "import cv2; print(cv2.__version__)" # 期望输出:3.2.0如果输出不是3.2.0,说明系统里还有别的 OpenCV 版本在干扰,用python3 -c "import cv2; print(cv2.__file__)"看加载的是哪个文件,把路径不对的那个从PYTHONPATH里去掉。
第二条验证 contrib 模块,这是 3.2 跟 4.x 差异最大的地方:
import cv2 # 确认 xfeatures2d 存在 print(hasattr(cv2, 'xfeatures2d')) # 创建 SIFT 检测器,3.2 里 SIFT 在 xfeatures2d 下 sift = cv2.xfeatures2d.SIFT_create() print("SIFT OK")这段代码跑通,说明 contrib 编进来了,SIFT 可用。如果hasattr返回 False,回第 5.4 节排查。注意 4.x 里 SIFT 已经挪到主模块,cv2.SIFT_create()直接可用,所以这段代码在 4.x 上跑会报AttributeError,反过来也能用来确认你装的确实是 3.2。
第三条做一次完整的图像读写和特征检测,模拟真实使用场景:
import cv2 import numpy as np # 生成一张测试图,画个圆 img = np.zeros((200, 200, 3), dtype=np.uint8) cv2.circle(img, (100, 100), 50, (0, 255, 0), 2) # 转灰度,3.2 的 cvtColor 用法和 4.x 一致 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 用 SIFT 检测关键点 sift = cv2.xfeatures2d.SIFT_create() kp = sift.detect(gray, None) print(f"检测到 {len(kp)} 个关键点") # 存图验证 imwrite 可用 cv2.imwrite("/tmp/opencv_test.png", img) print("图像写入成功")这段代码覆盖了cvtColor、SIFT_create、detect、imwrite四个常用接口,跑通说明核心模块、contrib、图像编解码都正常。如果detect返回 0 个关键点,可能是圆太简单,SIFT 没检出特征,换成一张真实照片再试。imwrite报错的话,检查/tmp写权限和libpng是否装好。
三条验证都过了,这套 OpenCV 3.2 环境就算真正落地了。从那以后我每次装完 OpenCV,不管 3.2 还是 4.x,都会强制走一遍「版本号 + contrib + 实际读写」这三步,绝不靠import cv2不报错就下结论——血泪经验,import成功但xfeatures2d缺失的情况太常见了。希望帮到你。
本文还有配套的精品资源,点击获取