
简介OpenCV 3.2 面向计算机视觉、机器学习方向的 C 开发者与高校学生提供该版本在 Windows 环境下编译、链接及二次开发所需的头文件与库文件可用于图像处理、特征检测、目标识别、视频分析和相机标定等项目的环境搭建。压缩包共 178 个文件其中 116 个 hpp 与 57 个 h 头文件构成主要接口声明另有 3 个 dll 动态库和 2 个 lib 静态库整体约 25.19MB便于按模块查阅和工程引用。目前已有 752 人学习下载说明其在 OpenCV 3.2 环境配置与版本适配场景中具有一定参考价值。资源涵盖 core、imgproc、videoio、calib3d、aruco 及 DNN 等模块的相关接口读者可据此完成 Visual Studio 等工程的包含目录、库目录与依赖项配置也可用于对照学习各模块的 C 接口组织方式为图像滤波、特征匹配、目标检测和视频处理等实践提供底层支持。1. 从一行 import 报错说起opencv 3.2 的环境边界在哪前阵子帮人复现一个老图像处理 Demo代码里import cv2之后直接调cv2.SIFT()机器上 apt 装的版本早就是 4.xcv2.SIFT早就不在了直接报属性不存在。退回去装opencv 3.2源码包又卡在 Python 3.8 上编不过cv2.cpp 一路报错编译到一半就停。折腾两天才认清楚3.2.0 是 2016 年底的版本它认的 Python 是 2.7 和 3.5编译器落在 gcc 4.8 到 5.4 最稳SIFT、SURF 那批算法还在 opencv_contrib 的 xfeatures2d 里待着。这类老环境在复现历史项目、跑老论文代码时非常常见装不好就是编译中断、import 半途崩掉、摄像头打不开。这篇记的就是我重装 opencv 3.2 的完整过程版本怎么配、cmake 怎么写、cv2.so 怎么放、出问题怎么救。2. 装前把环境钉死opencv 3.2 的版本搭配与依赖清单opencv 3.2 这种老版本最怕的不是命令写错是环境没钉死。同一份源码在 Python 3.5 上二十分钟编完在 Python 3.8 上能报一堆 C API 找不到。所以动手之前先花十分钟把版本、依赖、目录三件事定下来后面能省掉大半天。2.1 三套组合Python 2.7、Python 3.5 和纯 C先把三条常见路线摆出来选一条走到底别中途混着来。混着来最典型的翻车是Python 2 的 cv2.so 和 Python 3 的装进同一个目录然后import cv2时灵时不灵这种玄学问题排查起来很费劲。组合系统Python编译器适用场景AUbuntu 16.04 LTS2.7.12gcc 5.4老代码、老脚本原样复现BUbuntu 16.04 LTS3.5.2gcc 5.4新写的脚本仍要用 xfeatures2dCUbuntu 16.04 / CentOS 7不启用gcc 5.4 / 4.8只做 C 工程不碰 Python 绑定几个经验值。第一Python 3.6 及以上别尝试编 opencv 3.2 的 Python 绑定CPython 的 C API 在这几个小版本里改过源码里的切片和字符串接口对不上报错能拉一屏常见做法是退回 3.5或者干脆只编 C 部分。第二numpy 也别装太新3.2 时代的代码是按 numpy 1.11 上下写的装到 1.20 以后容易出现类型判断上的兼容问题装 2.x 基本必崩。第三如果只是要 C 能力BUILD_opencv_python3OFF关掉绑定能省掉一半的依赖麻烦。Windows 那边情况简单些opencv 3.2 官方提供自解压的预编译包解压后把build\x64\vc14\bin塞进 PATH工程里配好 include 和 lib 目录就行不需要自己编。但预编译包不带 contrib 模块要用 SIFT 还是得自己编所以下面的流程在 Windows 上换成 CMake GUI 也能走通。2.2 依赖包一次装齐apt 与 yum 的差异依赖最怕装一半编到某个模块才发现缺库又得从头来。我一般一次性装齐按用途分四组记编译工具、图像格式、视频编解码、GUI 与数学库。# 编译工具链与构建工具 sudo apt-get update sudo apt-get install -y build-essential cmake git pkg-config # 图像格式支持jpeg / png / tiff / jasper sudo apt-get install -y libjpeg8-dev libpng12-dev libtiff5-dev libjasper-dev # 视频编解码与摄像头采集 sudo apt-get install -y libavcodec-dev libavformat-dev libswscale-dev \ libv4l-dev libxvidcore-dev libx264-dev # GUI 与数学加速 sudo apt-get install -y libgtk2.0-dev libatlas-base-dev gfortran # Python 3.5 开发头文件与 numpy sudo apt-get install -y python3.5-dev python3-numpy每组的用途得说清楚不然缺了不知道缺在哪。build-essential提供 gcc、g、makecmake 负责生成构建文件pkg-config 决定后面 C 工程能不能用一条命令拿到编译参数。libjpeg8-dev、libpng12-dev、libtiff5-dev对应 imread 和 imwrite 的三种主流格式缺了不会编译失败但运行时会返回空 Mat这种静默失败最难查。libjasper-dev是 JPEG2000 支持某些新系统源里已经没有这个包装不上就加-D WITH_JASPEROFF关掉不影响主要功能。视频那组是关键。libavcodec-dev、libavformat-dev、libswscale-dev提供 FFmpeg 的编解码能力缺了VideoCapture打不开 mp4摄像头也可能读不出帧。libv4l-dev是 Linux 下摄像头采集的兼容层笔记本上跑实时处理必须装。GUI 这组里libgtk2.0-dev决定imshow()能不能弹出窗口。opencv 3.2 默认走 GTK2装成 GTK3 的话 cmake 会警告然后关掉 highgui 的窗口支持程序能跑但看不到图。libatlas-base-dev提供 BLAS 加速矩阵运算快一截gfortran是 ATLAS 的编译依赖漏了会链接报错。CentOS 7 上换成 yum包名对应关系是gcc-c换 build-essentialgtk2-devel换 libgtk2.0-devlibjpeg-turbo-devel换 libjpeg8-devjasper-devel换 libjasper-dev还要先yum install -y epel-release打开额外源不然一堆包装不上。2.3 源码包与目录规划opencv 3.2 的源码我习惯放固定目录编坏了直接删掉重来不污染家目录。# 建统一源码目录权限交给自己 sudo mkdir -p /opt/src sudo chown -R $USER:$USER /opt/src cd /opt/src # 主库固定拉 3.2.0 标签别用 master git clone --branch 3.2.0 --depth 1 https://github.com/opencv/opencv.git opencv-3.2.0 # contrib 模块必须同版本版本错位是编译失败的高发原因 git clone --branch 3.2.0 --depth 1 https://github.com/opencv/opencv_contrib.git opencv_contrib-3.2.0--branch 3.2.0锁死标签--depth 1只拉最新一次提交省一半下载时间。contrib 的版本必须和主库完全一致3.2.0 对 3.2.0差一个小版本都会在 cmake 阶段报模块接口不匹配。我见过有人主库拉 3.2、contrib 拉 3.4编到 xfeatures2d 直接挂掉回头查半天以为是编译器问题。目录结构上主库和 contrib 平级放后面 cmake 里OPENCV_EXTRA_MODULES_PATH指到 contrib 的modules子目录注意是modules不是 contrib 根目录少写一层等于没配。3. CMake 配置与编译opencv 3.2 参数逐项拆解源码躺好了接下来是最容易出岔子的一段。cmake 这步不是敲完回车就完事得看输出make 这步不是并发拉满就快得看内存。两件事都做对后面安装和绑定基本是顺的。3.1 一份能跑通的 cmake 命令先把命令贴出来再逐项解释。这套参数对应的是 2.1 里的组合 BUbuntu 16.04 Python 3.5 带 contrib。cd /opt/src/opencv-3.2.0 mkdir -p build cd build cmake -D CMAKE_BUILD_TYPERELEASE \ -D CMAKE_INSTALL_PREFIX/usr/local \ -D INSTALL_C_EXAMPLESOFF \ -D INSTALL_PYTHON_EXAMPLESON \ -D OPENCV_EXTRA_MODULES_PATH/opt/src/opencv_contrib-3.2.0/modules \ -D BUILD_EXAMPLESOFF \ -D BUILD_TESTSOFF \ -D WITH_CUDAOFF \ -D WITH_QTOFF \ -D WITH_GTKON \ -D WITH_FFMPEGON \ -D BUILD_opencv_python2OFF \ -D BUILD_opencv_python3ON \ -D PYTHON3_EXECUTABLE/usr/bin/python3.5 \ -D PYTHON3_INCLUDE_DIR/usr/include/python3.5m \ -D PYTHON3_LIBRARY/usr/lib/x86_64-linux-gnu/libpython3.5m.so \ -D PYTHON3_NUMPY_INCLUDE_DIRS/usr/lib/python3/dist-packages/numpy/core/include \ -D PYTHON3_PACKAGES_PATH/usr/lib/python3/dist-packages \ .. 21 | tee cmake.log命令来自源码根目录下的 build 子目录所以最后是..。输出用tee存一份编不过时不用往上翻终端。参数取舍逐条说。CMAKE_BUILD_TYPERELEASE开优化Debug 版本会大出好几倍跑生产代码没必要。CMAKE_INSTALL_PREFIX/usr/local是安装根头文件落到/usr/local/include库落到/usr/local/libPython 绑定落到/usr/lib/python3/dist-packages这几个路径后面都要用到。OPENCV_EXTRA_MODULES_PATH是 contrib 的入口指向modules子目录。BUILD_TESTSOFF和BUILD_EXAMPLESOFF是省时间的关键测试用例能占掉三成编译量第一次装环境完全没必要编。WITH_CUDAOFF除非机器上真有能用的显卡和 CUDA 工具链否则一定关掉。opencv 3.2 的 CUDA 支持对 cuda 版本很挑编到cudaarithm报一堆模板错误是常态。WITH_QTOFF是因为 Qt 版窗口要额外装 Qt5 开发包用它不如用 GTK 省事WITH_GTKON对应 apt 里装的 libgtk2.0-dev两个都关掉的话imshow直接不可用。PYTHON3_*这五个是 Python 绑定的命门。EXECUTABLE指解释器INCLUDE_DIR指头文件目录LIBRARY指libpython3.5m.so的完整路径NUMPY_INCLUDE_DIRS指 numpy 的 C 头文件位置PACKAGES_PATH指 cv2.so 的落地目录。路径写错不会报 cmake 错误只会在输出里显示Python 3: NO然后编完发现根本没有 cv2.so。所以 cmake 跑完必须看输出重点看三行Python 3:后面是不是 YES 并带出版本号和路径To be built:列表里有没有python3和xfeatures2dFFMPEG:是不是 YES。这三行不对后面不用编改了参数重跑 cmake 只要几秒。3.2 编译阶段make -j 的数字怎么定并发数是另一处容易翻车的地方。make -j拉满能把编译时间压到最短也能让进程被系统直接杀掉报一句internal compiler error: Killed看着像编译器 bug其实是内存不够。# 先看核数与可用内存 nproc free -h # 保守起点4 核 8G 内存用 -j4内存紧张用 -j2 make -j4 21 | tee build.log经验值是每个编译任务按 1GB 内存估。opencv 3.2 的dnn、imgproc这类模块编译时单进程能吃 1.5GB 上下4G 内存的机器上make -j8基本必挂。报 Killed 就减并发或者临时加个 swap 文件兜底sudo fallocate -l 2G /swapfile建 2G 交换分区编完再删掉。这个血泪经验值一条宁可多花二十分钟也别让编译跑到 80% 被杀掉重来。编译时间参考4 核 8G 的虚拟机上关掉测试和示例、带 contrib、不带 CUDA大约 25 到 40 分钟。如果十分钟就结束多半是某个模块在 cmake 阶段被关掉了回头翻 cmake.log 看To be built列表。编译过程中的警告可以忽略但 error 要立刻停。最常见的是 ffmpeg 相关头文件找不到对应就是 2.2 里视频那组依赖没装全补装后不用重新 cmake直接再 make 即可增量编译只编失败的那个模块。3.3 安装与动态库路径编完之后make install把产物复制到/usr/local但系统默认不认这个路径下的动态库不处理的话运行时报error while loading shared libraries: libopencv_core.so.3.2。这一步不能省。sudo make install # 让系统动态链接器认识 /usr/local/lib sudo sh -c echo /usr/local/lib /etc/ld.so.conf.d/opencv.conf sudo ldconfig # 确认库已经被缓存到 sudo ldconfig -v | grep opencvldconfig读取/etc/ld.so.conf及其子目录下的配置把库路径写入缓存。第三行能看到libopencv_core.so.3.2这类条目就说明注册成功。如果之前装过 apt 版的 opencv/usr/lib/x86_64-linux-gnu下可能还留着一份 4.x 的库ldconfig的搜索结果里两版并存时链接顺序会决定实际用哪一版。稳妥做法是先apt-get remove掉旧包或者用LD_LIBRARY_PATH/usr/local/lib在运行时显式指定。4. Python 绑定落地让 cv2 稳定被 import 到的三种做法C 库装好了Python 侧还不一定能用。cv2.so 生成了但不在 sys.path 里是新手最常见的一道墙。这章把「找文件、放对位置、验路径」三步走完。4.1 先确认 cv2.so 到底生成了没有别急着 import先找文件。找不到文件说明 cmake 里的 PYTHON3 参数就没生效再怎么折腾路径都没用。# 在安装目录里找 Python 绑定产物 find /usr/local/lib -name cv2*.so # 看当前解释器的模块搜索路径 python3.5 -c import sys; [print(p) for p in sys.path]第一条命令正常应该输出类似/usr/local/lib/python3.5/dist-packages/cv2.so的结果。3.2 时代产物的文件名通常就是朴素的cv2.so不像新版本带 ABI 后缀。搜不到的话回 cmake.log 里搜Python 3看是不是 NO或者PYTHON3_PACKAGES_PATH指到了一个不存在的目录导致写不进去。第二条命令列出 sys.path确认目标目录在里面。Ubuntu 16.04 的 Python 3.5 一般包含/usr/lib/python3/dist-packages和/usr/local/lib/python3.5/dist-packages两条如果安装路径不在这两条里就得靠下一步处理。4.2 软链进 site-packages最省事我一般用软链不复制。复制的话以后重编一次就得手动同步一次容易忘。# 把编译产物链到解释器能认的目录 sudo ln -sf /usr/local/lib/python3.5/dist-packages/cv2.so \ /usr/lib/python3/dist-packages/cv2.so # 验证 import 与版本 python3.5 -c import cv2; print(cv2.__version__)-s是软链-f是存在就覆盖两个一起用可以反复执行不出错。左边是实际产物右边是 sys.path 里的目录。输出版本号3.2.0就通了。不想动系统目录的话用环境变量也行export PYTHONPATH/usr/local/lib/python3.5/dist-packages:$PYTHONPATH写进~/.bashrc长期生效。缺点是换用户、换 shell、跑 cron 任务时环境变量不继承容易出「我这儿明明能跑」的争议。团队协作的机器上我还是倾向软链路径写死在系统里谁登进来都一样。如果两个 Python 版本共存务必确认软链指对了目录。python2.7和python3.5的 dist-packages 是两个不同目录链错的表现是 Python 3 能 import、Python 2 报错或者反过来。4.3 pkg-config 与 C 工程引用纯 C 工程不需要 cv2.so但需要编译参数。opencv 3.2 装完后会在/usr/local/lib/pkgconfig下生成opencv.pcpkg-config 靠它给出 include 和 lib 路径。# 让 pkg-config 找到 opencv.pc export PKG_CONFIG_PATH/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH # 查看版本与编译参数 pkg-config --modversion opencv pkg-config --cflags --libs opencv第二条命令输出一串-I/usr/local/include/opencv ... -lopencv_core -lopencv_imgproc ...把这串直接塞进 g 就能编。PKG_CONFIG_PATH同样建议写进/etc/profile.d/下的脚本别只放在当前会话不然换个终端又得重新 export。写 CMake 工程的话更简单find_package(OpenCV 3.2 REQUIRED)之后用${OpenCV_INCLUDE_DIRS}和${OpenCV_LIBS}版本号写 3.2 能挡住误用到 4.x 的情况。5. 避坑记录opencv 3.2 编译安装最容易翻车的五个地方下面五条都是我自己撞过或者帮人救过的按「现象 → 原因 → 解决」记照着对号入座基本能定位。5.1 ippicv 下载卡住编译停在 30%现象make 跑到opencv_core附近卡住不动日志里反复出现下载ippicv_linux_20151201.tgz的超时信息十几分钟没进展。原因3.2 的构建脚本会在 cmake 阶段从外网拉 ippicv、ffmpeg 这类第三方二进制包网络不稳就一直重试。解决手动下载对应的 tgz放到源码目录的.cache/ippicv/下文件名必须和脚本里写的一致然后重新 cmake。或者 cmake 时加-D WITH_IPPOFF直接关掉这套加速库对功能没有影响只是某些滤波运算慢一点。5.2 make 被 Killed报 internal compiler error现象编译到一半进程消失终端留下c: internal compiler error: Killed (program cc1plus)。原因并发数超过物理内存系统 OOM killer 直接杀掉编译进程看起来像编译器崩了。解决make -j2降并发或者加 2G swap 兜底。别迷信-j$(nproc)虚拟机上 nproc 是 8 但内存只有 4G 的情况太常见了。5.3 Python 3.6 及以上编不过 Python 绑定现象cmake 显示Python 3: YESmake 跑到opencv_python3模块时 cv2.cpp 报一堆标识符未声明。原因3.2 的绑定代码写于 CPython 3.5 时代后续小版本调整过部分 C API 的签名和宏。解决装 3.5 的解释器和开发包cmake 里把PYTHON3_EXECUTABLE、PYTHON3_INCLUDE_DIR、PYTHON3_LIBRARY三条全部指到 3.5 上重新 cmake。不想退版本的话就-D BUILD_opencv_python3OFF只留 C。5.4 import cv2 报 undefined symbol现象import cv2抛ImportError: ... undefined symbol: _ZN2cv...或者提示某个libopencv_*.so.3.2找不到。原因cv2.so 找到了但它依赖的动态库版本不对机器上残留了 apt 版 opencv 的旧库链接时抢在前面。解决先apt-get remove掉python-opencv、libopencv-dev这类旧包再sudo ldconfig刷新缓存然后ldd cv2.so | grep opencv看每个依赖解析到哪个路径确认全部指向/usr/local/lib。必要时用LD_LIBRARY_PATH/usr/local/lib强制优先。5.5 imshow 弹不出窗口或摄像头读不到帧现象脚本跑到cv2.imshow直接报The function is not implemented或者VideoCapture(0)返回 False。原因前者是 GTK 开发包缺失cmake 阶段把 highgui 的 GUI 后端关掉了后者是视频采集依赖没装全或者设备权限不够。解决sudo apt-get install libgtk2.0-dev pkg-config之后删掉 build 目录重新 cmake看输出里GTK 2.x:是不是 YES。摄像头问题先ls /dev/video*确认设备存在再sudo usermod -aG video $USER加权限重新登录生效。6. 装完怎么验三条命令确认 opencv 3.2 真的跑通装完不验等于没装。我见过太多「编译成功」但一跑就崩的情况下面三条从 Python、C、功能能力三个层面各验一次全部过了才算收工。6.1 Python 侧版本、路径、模块能力import cv2 import numpy as np # 1. 版本与编译信息 print(version:, cv2.__version__) print(python bindings:, cv2.__file__) # 2. 基础图像运算画个圆再转灰度 img np.zeros((200, 300, 3), dtypenp.uint8) cv2.circle(img, (150, 100), 60, (0, 255, 0), -1) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) print(mean:, round(float(gray.mean()), 2)) # 3. 确认 contrib 里的 xfeatures2d 是否可用 sift cv2.xfeatures2d.SIFT_create() kp sift.detect(gray, None) print(keypoints:, len(kp))第一段输出3.2.0和 cv2.so 的绝对路径路径必须指向你软链的那个位置指到别处说明还有旧版本在抢。第二段验证 numpy 与 Mat 的互转链路均值能打出来说明内存布局对得上。第三段是 3.2 这个版本的特色SIFT 在 xfeatures2d 里能创建出对象并检出关键点说明 contrib 编进去了这一步过不了就说明OPENCV_EXTRA_MODULES_PATH没配对。6.2 C 侧pkg-config 能否一条命令编过#include opencv2/opencv.hpp #include iostream int main() { // 生成一张 300x200 的画布并画圆 cv::Mat img cv::Mat::zeros(200, 300, CV_8UC3); cv::circle(img, cv::Point(150, 100), 60, cv::Scalar(0, 255, 0), -1); std::cout opencv version: CV_VERSION std::endl; std::cout mat size: img.cols x img.rows std::endl; cv::imwrite(out.png, img); return 0; }g verify.cpp -o verify $(pkg-config --cflags --libs opencv) ./verify ls -lh out.pngCV_VERSION是编译期宏打出来的是头文件对应的版本和运行时库版本不一致会暴露混装问题。能编过、能跑出3.2.0、能落地一个 png 文件说明头文件、库、链接路径三处全对。6.3 功能能力视频与设备这两项单独看# 查看编译期开启了哪些能力重点看 FFMPEG 与 GUI python3.5 -c import cv2; infocv2.getBuildInformation(); print(info) | grep -E FFMPEG|GUI|GTK输出里FFMPEG: YES和GUI: GTK两行是关键缺了任意一项视频和窗口相关的代码都跑不通。这两项在 cmake 阶段就定了事后补不了只能改参数重编所以验的时候顺手看一眼getBuildInformation()的输出最保险。最后是一个小习惯把上面三条验证命令写成一个check_opencv.sh放在/opt/src下以后每次重装或者换机器先跑这个脚本再动项目代码。从那以后我每次装完 opencv 都强制走一遍这套验证不看到3.2.0和 keypoints 的数字就不往下写业务代码——之前有一次偷懒跳过结果项目跑到半夜才发现 cv2.so 链的是旧版本白白多花三小时。希望帮到你。本文还有配套的精品资源点击获取