多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Linux 下编译 OpenCV 4.2 与 contrib 的避坑指南:从源码到物体识别计数

Linux 下编译 OpenCV 4.2 与 contrib 的避坑指南:从源码到物体识别计数 简介本资源为在 Linux 环境下可直接编译通过的 OpenCV 4.2 完整源码包并整合了经作者修复的 opencv_contrib 扩展库面向从事计算机视觉、人工智能开发及运维部署的工程师与学习者。官方 opencv_contrib 在 Linux 编译时常因缺少相关文件、头文件路径找不到而报错本包已针对这些问题完成修改可省去大量排错时间。压缩包共 8752 个文件约 146.06MB以 cpp、hpp、h 等 C 源码与头文件为主体辅以 png、jpg 测试图像以及 py、java、cu、cmake、xml 等多语言与构建脚本覆盖核心模块、扩展模块、示例与文档。已有 493 人学习下载。读者可据此快速搭建可编译的视觉开发环境直接使用 contrib 中的特征提取、目标跟踪等扩展算法并参考目录中的示例与教程理解模块组织方式适合需要稳定编译与二次开发的中高级开发者。1. 为什么我宁愿用这份改过的 OpenCV 4.2 源码也不碰官网 contrib在 Linux 上编译过 OpenCV 的人大概都有过这种体验主库opencv顺顺利利编完一加上opencv_contrib扩展库cmake阶段就开始报缺文件make到一半又冒出某个头文件找不到最后卡在tracking或xfeatures2d模块上一晚上就没了。这份资源就是针对这个场景来的——它是 OpenCV 4.2 加上配套的opencv_contrib作者把官网版本在 Linux 下编译时缺文件、头文件路径对不上的问题修过能直接编过。适合谁做计算机视觉、图像处理、物体识别计数这类项目需要在 Ubuntu 或其它 Linux 发行版上从源码装 OpenCV并且明确要用到 contrib 里那些非免费模块比如 SIFT、SURF、Tracker、人脸相关算法的工程师。如果你只是pip install opencv-python就够用那这份源码对你意义不大但只要你要自己编译、要 CUDA 加速、要用 contrib这份改过的包能省掉大量翻车时间。2. 先搞清楚 contrib 到底补了什么模块清单与选型判断2.1 主库和 contrib 的分工别装重复了OpenCV 从 4.x 开始把一部分算法从主仓库拆到了opencv_contrib原因是专利和授权问题。主库opencv里放的是稳定、免费、商用无风险的模块比如core、imgproc、imgcodecs、videoio、highgui、calib3d、dnn、features2d这些。而opencv_contrib里放的是实验性或专利受限的模块典型的有模块作用是否常被用到xfeatures2dSIFT、SURF、ORB 扩展等特征非常高trackingKCF、CSRT、MOSSE 等目标跟踪高face人脸识别相关中text文字检测识别中arucoAR 标记识别中bgsegm背景分割中ximgproc扩展图像处理中sfm运动恢复结构低stereo立体匹配扩展低选型判断很简单你要用 SIFT 做特征匹配、要用 Tracker 做目标跟踪、要做基于 OpenCV 的物体识别和计数那 contrib 基本跑不掉。反过来如果你只做基础的图像读写、缩放、滤波、边缘检测主库足够没必要为了 contrib 去折腾编译。2.2 为什么官网 contrib 在 Linux 下容易编不过官网的opencv_contrib是跟着主库版本走的但两者在发布节奏上并不完全同步。4.2 这个版本上常见的问题有几类一是 contrib 里某些模块引用了主库里已经改名或挪位置的头文件#include路径对不上二是cmake配置阶段OPENCV_EXTRA_MODULES_PATH指过去之后某些模块的CMakeLists.txt里依赖检测逻辑有缺陷导致缺文件报错三是tracking模块里一些实现文件在 Linux 下的路径大小写敏感问题。这份资源的价值就在于作者把这些坑提前填了你拿到的是改过的源码不是官网原版。提示不要拿官网的 contrib 去配这份主库也不要拿这份 contrib 去配官网主库版本和修改是对应的混用大概率继续报错。2.3 编译前先把依赖装齐别让 cmake 替你猜在 Ubuntu 上编译 OpenCV依赖不齐是 cmake 报错的第一大来源。我一般会先把这些装上避免编到一半才发现缺东西# 基础编译工具 sudo apt update sudo apt install -y build-essential cmake git pkg-config # 图像和视频编解码依赖 sudo apt install -y libjpeg-dev libtiff-dev libpng-dev sudo apt install -y libavcodec-dev libavformat-dev libswscale-dev libv4l-dev sudo apt install -y libxvidcore-dev libx264-dev # GUI 和数学库 sudo apt install -y libgtk-3-dev libatlas-base-dev gfortran # Python 绑定相关 sudo apt install -y python3-dev python3-numpy python3-pip这段命令的逻辑是build-essential和cmake是编译骨架libjpeg、libtiff、libpng决定你能不能读写常见图片格式libavcodec那一串是视频 IO 的底层libgtk-3-dev是highgui显示窗口用的不装的话imshow直接不可用libatlas-base-dev和gfortran是给矩阵运算加速的。参数上没什么可调的按发行版对应包名装就行CentOS 系换成yum或dnf对应包。3. 从解压到 cmake把 contrib 挂进主库的正确姿势3.1 目录结构先摆对OPENCV_EXTRA_MODULES_PATH 才不会指错拿到这份资源后先解压确认两个目录是平级的。常见做法是建一个工作目录把主库和 contrib 都放进去mkdir -p ~/opencv_build cd ~/opencv_build # 假设资源解压后得到 opencv 和 opencv_contrib 两个目录 ls # 应该看到opencv opencv_contribOPENCV_EXTRA_MODULES_PATH这个 cmake 变量必须指向 contrib 下的modules目录而不是 contrib 根目录。这是新手最容易指错的地方指错了 cmake 不会报致命错误但 contrib 模块一个都不会被编进去最后你发现cv2.xfeatures2d根本不存在。3.2 cmake 配置把关键开关一次说清进入主库目录建build然后跑 cmake。下面这份配置是我在 4.2 上常用的参数含义逐条说明cd ~/opencv_build/opencv mkdir build cd build cmake -D CMAKE_BUILD_TYPERELEASE \ -D CMAKE_INSTALL_PREFIX/usr/local \ -D OPENCV_EXTRA_MODULES_PATH~/opencv_build/opencv_contrib/modules \ -D INSTALL_PYTHON3_EXAMPLESON \ -D BUILD_EXAMPLESOFF \ -D WITH_CUDAOFF \ -D WITH_GTKON \ -D OPENCV_GENERATE_PKGCONFIGON \ -D PYTHON3_EXECUTABLE$(which python3) \ -D PYTHON3_INCLUDE_DIR$(python3 -c from sysconfig import get_path; print(get_path(include))) \ -D PYTHON3_PACKAGES_PATH$(python3 -c from sysconfig import get_path; print(get_path(purelib))) \ ..逐条解释CMAKE_BUILD_TYPERELEASE开优化比 Debug 快很多CMAKE_INSTALL_PREFIX/usr/local是安装位置后面pkg-config和 Python 找库都靠它OPENCV_EXTRA_MODULES_PATH就是 contrib 的 modules 路径必须绝对路径或正确相对路径WITH_CUDAOFF是因为这份资源没提 CUDA如果你有 NVIDIA 显卡且装了 CUDA可以改 ON但编译时间和依赖会陡增OPENCV_GENERATE_PKGCONFIGON会生成opencv4.pc方便用pkg-config编译 C 程序后面三个 Python 变量是为了让 Python 绑定装到当前解释器能找的地方避免出现ModuleNotFoundError: No module named cv2。注意如果你机器上有多套 PythonPYTHON3_EXECUTABLE一定要写清楚用哪个否则 cmake 可能挑到系统自带的旧版本编完 import 不进来。3.3 编译和安装make -j 不是越大越好cmake 跑完确认输出里能看到xfeatures2d、tracking这些 contrib 模块被列出来再开始编# 查看 CPU 核心数决定 -j 的值 nproc # 假设是 8 核用 -j8内存小的机器建议 -j4 甚至 -j2 make -j8 # 编译完成后安装 sudo make install sudo ldconfigmake -j的数值不是越大越好。OpenCV 编译时单个编译单元内存占用不低尤其是dnn和 contrib 里一些模板重的模块-j开太大容易触发 OOM表现为某个cc1plus进程被 kill报错信息还不明显。血泪经验是8G 内存的机器用-j416G 以上再考虑-j8。sudo ldconfig是刷新动态库缓存不跑的话运行程序可能提示找不到libopencv_core.so.4.2。4. 验证 contrib 是否真的编进去了别只看 make 成功4.1 Python 侧验证xfeatures2d 和 tracking 能不能 importmake成功不代表 contrib 可用必须实际验证。Python 下最直接import cv2 print(cv2.__version__) # 应输出 4.2.x # 验证 xfeatures2dSIFT 在 4.2 已进主库但 SURF 等仍在 contrib try: surf cv2.xfeatures2d.SURF_create(400) print(xfeatures2d OK) except AttributeError as e: print(xfeatures2d 不可用:, e) # 验证 tracking try: tracker cv2.TrackerCSRT_create() print(tracking OK) except AttributeError as e: print(tracking 不可用:, e)如果cv2.__version__输出的是 4.2.x但xfeatures2d报module cv2 has no attribute xfeatures2d说明 contrib 没编进去回去检查OPENCV_EXTRA_MODULES_PATH是否指到了modules目录。如果 import cv2 直接失败报ModuleNotFoundError那是 Python 绑定路径问题检查 cmake 里的PYTHON3_PACKAGES_PATH和你当前python3的site-packages是否一致。4.2 C 侧验证pkg-config 和最小编译单元C 项目里用 contrib靠pkg-config拿编译参数最省事pkg-config --modversion opencv4 pkg-config --cflags --libs opencv4如果pkg-config报找不到opencv4说明opencv4.pc没生成或不在PKG_CONFIG_PATH里。可以手动找一下find /usr/local -name opencv4.pc # 如果找到了把它所在目录加到环境变量 export PKG_CONFIG_PATH/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH写一个最小 C 程序验证 contrib 的 Tracker#include opencv2/opencv.hpp #include opencv2/tracking.hpp #include iostream int main() { // 尝试创建 CSRT 跟踪器这是 contrib tracking 模块的类 cv::Ptrcv::Tracker tracker cv::TrackerCSRT::create(); if (tracker.empty()) { std::cout tracking 模块不可用 std::endl; return -1; } std::cout OpenCV CV_VERSION tracking OK std::endl; return 0; }编译命令g tracker_test.cpp -o tracker_test $(pkg-config --cflags --libs opencv4) ./tracker_test能输出OpenCV 4.2.x tracking OK就说明 contrib 的 tracking 模块真的链上了。这一步比看make日志靠谱得多因为有些模块编了但没装或者装了但链接时找不到。5. 避坑与排查编译 OpenCV 4.2 contrib 最常见的五类翻车5.1 现象cmake 报 “Could not find module” 或某个 contrib 模块被跳过原因OPENCV_EXTRA_MODULES_PATH指错了或者 contrib 目录里对应模块的CMakeLists.txt依赖没满足。这份资源虽然修过缺文件问题但如果你系统缺某个可选依赖对应模块仍可能被跳过。解决先确认路径指到opencv_contrib/modules然后在 cmake 输出里搜模块名看它是因为什么被跳过。常见的是缺libgoogle-glog-dev导致某些模块不编按需装上再重新 cmake。5.2 现象make 到 90% 多突然报错提示某个头文件 No such file原因contrib 里模块引用了主库的头文件但路径大小写或相对位置在 Linux 下对不上。官网原版在 4.2 上就有这个问题这份资源已经改过但如果你混用了别的版本 contrib问题会复现。解决确认用的是资源里配套的 contrib不要自己换版本。如果仍报错看报错的头文件名去主库modules下find一下实际位置对比 contrib 里的#include路径。5.3 现象Python 里 import cv2 成功但 xfeatures2d 或 tracking 报 AttributeError原因contrib 没被编进 Python 绑定或者编进去了但装到了另一个 Python 环境。cmake 时 Python 相关变量没配对是主因。解决重新 cmake 前先python3 -c import sys; print(sys.executable)确认解释器把PYTHON3_EXECUTABLE、PYTHON3_INCLUDE_DIR、PYTHON3_PACKAGES_PATH三个都显式指定。编完make install后用同一个解释器验证。5.4 现象make -j 过程中进程被 killed没有明确错误原因内存不足OOM killer 杀掉了编译进程。OpenCV 的dnn和部分 contrib 模块编译时内存峰值很高。解决降低-j数值比如从-j8降到-j2或-j1或者临时加 swap。别硬扛OOM 报错信息往往不指向真正原因容易误判成代码问题。5.5 现象程序运行时提示找不到 libopencv_xxx.so.4.2原因安装后没刷新动态库缓存或者安装路径不在ld.so.conf里。解决sudo ldconfig。如果还不行检查/etc/ld.so.conf.d/下有没有包含/usr/local/lib的配置没有就加一个再ldconfig。6. 进阶用这份源码做物体识别计数时几个能省时间的技巧物体识别和计数是 OpenCV 里很典型的落地场景配合 contrib 的tracking和xfeatures2d能做不少事。这里说几个我实际用下来能省时间的点。第一个是 SIFT 和 SURF 的选择。4.2 里 SIFT 已经进主库cv2.SIFT_create()直接可用不需要 contribSURF 仍在xfeatures2d里cv2.xfeatures2d.SURF_create()。如果你只是做特征匹配优先用 SIFT省得依赖 contrib。但如果你的项目已经编了 contribSURF 在速度上有时更有优势可以两个都试用cv2.BFMatcher配ratio test对比匹配点数量和耗时。第二个是 Tracker 的选型。contrib 的tracking模块里有 KCF、CSRT、MOSSE 等。CSRT 精度高但慢KCF 快但遮挡下容易丢MOSSE 最快但精度最低。做计数场景如果目标移动快、遮挡少KCF 够用如果目标会被遮挡CSRT 更稳。切换只需要改cv2.TrackerCSRT_create()为cv2.TrackerKCF_create()接口一致。第三个是编译时把不需要的模块关掉。contrib 里模块很多全编很耗时。如果你明确不用sfm、stereo、text可以在 cmake 时用-D BUILD_opencv_sfmOFF这类参数关掉能明显缩短编译时间。具体模块名就是BUILD_opencv_加模块名。第四个是验证编译结果时别只跑一个 import。我一般会写一个小脚本把项目里实际要用的 contrib 类都实例化一遍比如SURF_create、TrackerCSRT_create、createBackgroundSubtractorMOG2这个在主库跑通了再开始写业务代码。这样能把环境问题一次性暴露出来而不是写到一半才发现某个模块没编进去。最后一个习惯每次换机器或重装系统我都会把 cmake 那行命令存成一个build.sh把 Python 路径、contrib 路径、开关都写死。从那以后我每次编译 OpenCV 都强制走一遍这个脚本不再手敲 cmake避免因为少写一个变量导致 contrib 没编进去、白等一小时。希望帮到你。本文还有配套的精品资源点击获取
返回列表