
Ubuntu 18.04 上装 OpenCV最折腾的不是代码本身而是各种依赖和版本的博弈。我前段时间为了跑相机雷达联合标定把系统里的 OpenCV 反反复复查了好几遍最后还是在 18.04 上源码编译了 OpenCV 4.5.5整个过程踩了不少坑也总结出一套最省心的流程。这篇教程就以 4.5.5 为例把每一步拆开讲清楚新手照着做也能顺利装出来。1. 为什么选择源码编译安装 OpenCV 4.51.1 apt、pip 与源码编译的取舍Ubuntu 18.04 上装 OpenCV 有三种常见方式apt install、pip install、源码编译。三条路我都走过先说结论想长期做 C 视觉开发、跑 ROS 相关工具或者给 Autoware 这类框架准备依赖源码编译是最靠谱的。apt install libopencv-dev一条命令确实快但 Ubuntu 18.04 源里的 OpenCV 是 3.2.02016 年的老版本。3.x 和 4.x 的 API 差异不小很多 4.x 才稳定的接口在 3.2 里根本不存在。比如 DNN 模块的很多新接口、ArUco 标记检测、G-API 流水线老版本要么缺失要么行为不一样。如果只是做简单图像处理apt 没问题但一旦涉及深度学习推理或者现代视觉算法老版本会卡得很死。pip install opencv-python能装到比较新的版本适合 Python 快速验证。但预编译的 wheel 有几个天然短板C 项目链不到这套库contrib 模块没有完整编译进去有些算法比如 SIFT、SURF 在预编译包里默认不开。你如果自己编译OPENCV_ENABLE_NONFREEON一开这些算法的专利开关就都解开了。源码编译最麻烦但可控性最强。可以指定 Python 版本生成 pkg-config 文件加入 contrib 模块按自己的 CPU 调编译参数。对于需要长期维护的工程环境这是唯一不会越用越乱的方式。1.2 版本选择与硬件兼容性标题写的 OpenCV 4.5实际上 4.5.x 是一个系列从 4.5.0 到 4.5.5。我建议直接用 4.5.5它是 4.5 分支的最后一个版本patch 修得最多同时兼容性和 API 风格也比较稳定。选 4.5 而不是更新版本主要考虑兼容性。很多老项目比如 VINS、Old Autoware还有不少相机标定工具都是在 4.5 时代写的换到 4.8、4.10 可能会遇到 API 变动导致编译失败。OpenCV 4.5 对系统要求也不苛刻官方最低 CMake 3.5.1但 Ubuntu 18.04 自带的 CMake 是 3.10.2编译 OpenCV 本身足够如果要同时编译其他新库可能会显老这个我在下一节单独说。2. 准备工作依赖环境与 Python 工具链2.1 更新软件源并安装编译工具安装之前先把系统更新一遍避免依赖冲突sudo apt update sudo apt upgrade -y然后安装编译工具链和基础工具sudo apt install -y build-essential cmake git pkg-configbuild-essential包含 gcc、g、make是编译 C 项目的三件套。cmake是 OpenCV 的构建系统git用来拉源码pkg-config后面验证版本和编译测试程序都要用。Ubuntu 18.04 自带的 CMake 版本是 3.10.2编译 OpenCV 4.5 没问题。但如果你和我一样经常要编译一些新出的第三方库3.10 就明显偏老了。检查一下当前版本cmake --version如果低于 3.15 рекомендуют用 pip 装一个新版 CMake简单省事pip3 install cmake --user装完后把~/.local/bin加入 PATH或者退出终端重新登录让终端优先使用新版 CMake。如果坚持不装 Python 环境那就只能从 CMake 官网下载源码编译激活码麻烦一些但也是标准做法。2.2 安装图像、视频与 GUI 相关依赖OpenCV 的模块系统很强但高 GUI、视频 IO 这些功能依赖外部库。不装的话编译能过功能却会缺。比如没有 GTK 库highgui模块起不了图形窗口跑cv2.imshow()直接报错没有 ffmpeg 相关库VideoCapture能读的文件格式会非常有限。下面这组依赖是我在 18.04 上实测过最完整的清单sudo apt install -y libgtk-3-dev libavcodec-dev libavformat-dev libswscale-dev libv4l-dev libxvidcore-dev libx264-dev libjpeg-dev libpng-dev libtiff-dev libatlas-base-dev libblas-dev liblapack-dev libprotobuf-dev protobuf-compiler libgoogle-glog-dev libgflags-dev libhdf5-dev逐个解释一下用途这样你知道哪些是刚需哪些是按需libgtk-3-devGUI 支持imshow窗口、滑动条都靠它。不做可视化可以跳过但做视觉开发基本都会用到。libavcodec-dev libavformat-dev libswscale-devffmpeg 的三个核心库视频解码、封装格式解析、图像缩放都依赖它们。装了之后 OpenCV 才能流畅处理 mp4、avi 等常见视频容器。libv4l-devV4L2 视频采集接口接 USB 摄像头必须。libxvidcore-dev libx264-dev视频编码器尤其是 x264H.264 编码的主要实现。libjpeg-dev libpng-dev libtiff-dev常见图像格式支持必装。libatlas-base-dev libblas-dev liblapack-dev线性代数库。OpenCV 的矩阵运算会用到 BLAS 后端装 ATLAS 是最省心的选择。libprotobuf-dev protobuf-compilerDNN 模块解析模型需要做深度学习推理建议装。libgoogle-glog-dev libgflags-dev日志和命令行解析库OpenCV 的一些工具模块会用到。libhdf5-devHDF5 数据格式支持在模型存储和科学计算场景下比较重要。如果你只想做最基础的图像处理可以少装一些但既然选择源码编译我建议一次装齐省得后面发现缺模块又重跑一遍 CMake。2.3 Python 开发头文件与 pip 环境想让编译出来的 OpenCV 提供 Python 接口也就是生成cv2模块必须装 Python 开发头文件sudo apt install -y python3-dev python3-pip python3-numpypython3-dev是很多人最容易漏的。没有它CMake 配置阶段找不到 Python.h结果就是 C 版 OpenCV 编译好了Python 的 cv2 模块根本没生成。python3-numpy是为了让 Python 接口能正确处理 numpy 数组格式OpenCV 的 Python API 底层就是 numpy 数组。这里需要提醒一句Ubuntu 18.04 默认 Python 是 3.6。如果你用 conda 或 pyenv 管理多个 Python 版本编译时一定要显式指定 Python 路径否则 CMake 大概率去找系统 Python生成的 cv2 装错位置conda 里 import 时就报错。具体参数在第 3 节讲。3. 源码下载与 CMake 配置核心参数逐项拆解3.1 下载 OpenCV 和 contrib 源码OpenCV 的源码建议从 GitHub 官方仓库拉取用--branch指定版本--depth 1只拉最近一次提交省掉大量历史记录下载体积会小很多cd ~ git clone --branch 4.5.5 --depth 1 https://github.com/opencv/opencv.git git clone --branch 4.5.5 --depth 1 https://github.com/opencv/opencv_contrib.git如果你只是想要主库不装 contrib那第一个仓库就够了。但我强烈建议把 contrib 一起拉下来因为很多实用模块在 contrib 里比如aruco、bgsegm、xfeatures2d。有一个必须注意的点opencv 和 opencv_contrib 的版本必须严格一致。如果 opencv 是 4.5.5contrib 必须是 4.5.5否则 CMake 配置阶段会报版本不匹配的警告甚至直接失败。如果 GitHub 下载速度不理想有两个处理办法一是用 GitHub 镜像地址替换二是直接到 OpenCV 官网 Releases 页面下载对应版本的 zip 包解压后目录结构是一样的。3.2 CMake 生成构建配置进入 opencv 目录创建 build 目录然后开始配置。用 build 目录是为了不污染源码目录这是 CMake 项目的标准做法cd ~/opencv mkdir build cd build cmake -D CMAKE_BUILD_TYPERELEASE \ -D CMAKE_INSTALL_PREFIX/usr/local \ -D OPENCV_ENABLE_NONFREEON \ -D OPENCV_EXTRA_MODULES_PATH~/opencv_contrib/modules \ -D WITH_TBBON \ -D WITH_V4LON \ -D WITH_OPENGLON \ -D OPENCV_GENERATE_PKGCONFIGYES \ -D BUILD_opencv_python3ON \ -D PYTHON3_EXECUTABLE$(which python3) \ -D BUILD_EXAMPLESOFF ..下面把每个关键参数拆开讲CMAKE_BUILD_TYPERELEASE编译 Release 版本做优化不带调试信息默认构建行为就是这样的。不要用 Debug除非你要调试 OpenCV 源码。CMAKE_INSTALL_PREFIX/usr/local安装目录。默认会装到/usr/local/include/opencv4和/usr/local/lib这是系统约定俗成的位置大部分程序都会自动搜索这里。如果你想装到指定目录比如/opt/opencv4.5可以改这个参数但后续所有链接 OpenCV 的项目都要找到这个路径会比较麻烦。OPENCV_ENABLE_NONFREEON这个开关控制的是 SIFT、SURF 这些专利算法的编译。不打开的话调用这些算法会直接报专利错误。除非有明确的授权顾虑否则建议打开。OPENCV_EXTRA_MODULES_PATH指向 contrib 模块目录。contrib 由很多独立模块组成编译系统会把这些模块和主库一起编译。WITH_TBBON开启 Intel TBB 并行后端多核 CPU 下能明显加速图像处理。前提是装了libtbb-dev如果没装CMake 会自动关掉 TBB但最好提前装好。WITH_V4LON启用 V4L 支持对 Linux 下的 USB 摄像头采集很重要稳定性会好很多。WITH_OPENGLON开启 OpenGL 互操作需要 3D 渲染的可视化工具会用到。OPENCV_GENERATE_PKGCONFIGYES这是 4.x 版本里很重要的一个开关。OpenCV 之前默认不生成opencv4.pc文件导致pkg-config --modversion opencv4查不到版本。这个参数打开后就会生成 pkg-config 配置文件后续编译 C 程序非常方便。BUILD_opencv_python3ON一定要显式打开否则 CMake 可能只编译 C 库。如果你不关心 Python 接口可以关掉但建议保持打开多一层保障。PYTHON3_EXECUTABLE指定 python3 的路径。如果你的环境里 Python 版本比较乱这一步能确保 CMake 把 Python 绑定到你指定的解释器上。BUILD_EXAMPLESOFF不编译示例代码省时间。如果你需要官方示例做参考可以打开但默认建议关闭。配置完成后CMake 会输出一个 Summary里面会列出检测到的模块、Python、Java 等信息。这时一定要检查几个关键项Python 3那一栏是不是YESInstall to路径是不是/usr/local还有下载的 ippicv 是否成功。如果 Python 3 显示NO回头去检查python3-dev是否安装以及PYTHON3_EXECUTABLE是否指定正确。如果你正在用 conda 环境CMake 配置时最好加上这三个参数否则生成的 cv2 很可能装错位置-D PYTHON3_EXECUTABLE$(which python3) -D PYTHON3_INCLUDE_DIR$(python3 -c from sysconfig import get_paths; print(get_paths()[include])) -D PYTHON3_PACKAGES_PATH$(python3 -c from sysconfig import get_paths; print(get_paths()[purelib]))这样能确保 Python 接口生成到当前环境对应的 site-packages 目录里。4. 编译、安装与环境变量配置4.1 make 编译的时间与资源管理配置成功后在 build 目录里执行make -j$(nproc)$(nproc)会自动读取 CPU 核心数比如 8 核机器就是make -j8。如果你的内存比较小比如 8GB 以下建议把并行数降下来用make -j4甚至make -j2否则内存可能吃满直接 OOM。我见过 16 核机器在编译 OpenCV 时如果直接-j16内存占用轻松超过 10GB内存不宽裕的主机确实会卡死。整个编译过程大约 20 到 50 分钟取决于机器性能。中途如果报错先把错误信息往上翻看是哪一个源文件出的问题。最常见的是缺头文件比如fatal error: zlib.h: No such file or directory那就是缺zlib1g-dev补装后再重新 make。改完依赖后建议直接继续make不用重新 cmake否则会重新编译大量文件浪费时间。编译过程中可以顺手做点别的但最好保持终端存活不要让它休眠。有些笔记本插着电源没事如果靠电池运行到了节能模式可能会挂起进程导致编译时间翻倍。4.2 安装并配置动态链接库编译完成后执行sudo make install sudo ldconfigmake install会把头文件、库文件、CMake 配置、pkg-config 文件拷贝到系统目录。ldconfig的作用是更新动态链接库缓存让程序运行时能找到libopencv_world.so.4.5。如果 OpenCV 安装到了/usr/local多数情况下 ldconfig 会自动扫描/usr/local/lib。但有些系统的/usr/local/lib并不在默认搜索路径里这时候要手动配置sudo sh -c echo /usr/local/lib /etc/ld.so.conf.d/opencv.conf sudo ldconfig这一步非常关键否则编译出来的程序一运行就会报error while loading shared libraries: libopencv_world.so.4.5: cannot open shared object file: No such file or directory然后检查 pkg-config 的路径。OpenCV 的.pc文件生成到/usr/local/lib/pkgconfig后如果pkg-config --modversion opencv4查不到需要把/usr/local/lib/pkgconfig加入PKG_CONFIG_PATHecho export PKG_CONFIG_PATH/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH ~/.bashrc source ~/.bashrc我个人的习惯是安装完立刻配置环境变量不然过几天开新终端链接失败的时候根本想不起来当初是怎么配的。5. 安装结果验证5.1 用 C 代码验证核心链接写一个最简单的 C 测试文件确认库和头文件都可用#include opencv2/opencv.hpp #include iostream int main() { std::cout OpenCV version: CV_VERSION std::endl; cv::Mat img(100, 100, CV_8UC3, cv::Scalar(0, 0, 255)); std::cout img size: img.cols x img.rows std::endl; return 0; }保存为test.cpp然后编译运行g test.cpp $(pkg-config --cflags --libs opencv4) -o test ./test看到OpenCV version: 4.5.5就说明 C 接口没问题。这里pkg-config opencv4的名字是opencv4不是opencv因为 OpenCV 4.x 生成的 pkg-config 名称就是这个。如果遇到Package opencv4 was not found回到第 4 节检查PKG_CONFIG_PATH是否配置正确。5.2 Python 接口验证进入 Python 环境执行python3 -c import cv2; print(cv2.__version__)如果显示4.5.5说明 Python 接口也 OK。如果报ModuleNotFoundError: No module named cv2优先检查 CMake 配置阶段BUILD_opencv_python3是否为 ON以及 Python3 的路径是否指对。这里有个经常踩的坑如果你之前用pip install opencv-python装过 cv2后来编译的版本可能被覆盖。执行python3 -c import cv2; print(cv2.__file__)看看路径如果指向 site-packages 而不是/usr/local/lib/python3.6/dist-packages那说明你的 Python 环境用的还是 pip 版和编译出来的 C 库不是一家人。开发时最好固定一种来源要么纯编译版要么纯 pip 版混用迟早出 bug。5.3 用 CMake 工程验证想确认自己的 CMake 项目能不能发现 OpenCV 4.5可以写一个简单的 CMakeLists.txtcmake_minimum_required(VERSION 3.10) project(TestOpenCV) find_package(OpenCV REQUIRED) message(STATUS OpenCV version: ${OpenCV_VERSION}) include_directories(${OpenCV_INCLUDE_DIRS}) add_executable(test main.cpp) target_link_libraries(test ${OpenCV_LIBS})然后在 build 目录里跑cmake .. makeCMake 找到 OpenCV 时会输出OpenCV version: 4.5.5。如果找不到通常是CMAKE_PREFIX_PATH没包含/usr/local因为find_package(OpenCV)会去/usr/local/lib/cmake/opencv4找配置文件。手动指定一下就行cmake -D CMAKE_PREFIX_PATH/usr/local ..6. 常见问题与排查实录6.1 ippicv 下载失败编译时卡在下载 ippicv是新手最容易遇到的一个问题。OpenCV 在编译时会自动下载 Intel IPP 的加速包但这个文件放在 GitHub 的 release 附件里网络环境不好的时候经常下不动。症状就是 CMake 输出长时间停在IPPICV: Download: ippicv_2020_lnx_intel64_20191018_general.tgz然后超时。解决办法有两个一是手动下载这个 tgz 放到本地然后修改~/opencv/3rdparty/ippicv/ippicv.cmake里对应的 URL 和路径指向本地文件二是干脆关掉 IPP-D WITH_IPPOFF不是所有机器都需要 IPP 加速关掉并不影响后期使用。我自己做视觉算法更看重可复现性所以直接-D WITH_IPPOFF省心也避免了下载卡住的问题。6.2 与 OpenGL/图形驱动相关的编译错误有些同学编译时会遇到类似No rule to make target /usr/lib/x86_64-linux-gnu/libGL.so的错误。这种多半是图形驱动或 OpenGL 相关依赖异常。先试sudo apt install libgl1-mesa-dev libglu1-mesa-dev然后删掉 build 目录重新跑 CMake。有时候旧 build 目录里的 CMakeCache 残留了错误路径重新配置前用rm -rf build重建最干净。6.3 与 ROS/其他 OpenCV 版本冲突如果装了 ROS 的 Desktop 版本ROS Melodic 自带 OpenCV 3.2并且会把/opt/ros/melodic/lib写进环境变量。这时候源码编译安装 OpenCV 4.5 后程序运行时可能链接到老版本的 .so导致行为诡异。我的经验是在.bashrc里把/usr/local/lib放到LD_LIBRARY_PATH的最前面或者编译 C 工程时显式用-I/usr/local/include/opencv4 -L/usr/local/lib -lopencv_world。如果项目本身是 ROS 节点在 CMakeLists 里用find_package(OpenCV 4.5 REQUIRED)并放在find_package(catkin ...)之后确保优先找到新版 OpenCV而不是 ROS 自带的老版本。6.4 Python 多版本导致的 cv2 装错位置如果你用 conda或者机器上有多套 Python编译时一定要显式指定 Python 路径。我踩过的坑是在 conda 环境里编译结果生成的 cv2 装到了系统 site-packagesconda 里 import 报错。后来查 CMake 的输出发现它默认找了系统 Python 3.6而不是 conda 里的 Python。解决办法就是在 CMake 配置时把PYTHON3_INCLUDE_DIR和PYTHON3_PACKAGES_PATH都指定到当前环境的路径。具体命令在第 3 节已经写了这里再强调一遍路径一定要用which python3确认不能想当然。6.5 编译时间过长如何止损如果编译到一半发现进度实在太慢不想等了可以停掉把 CMake 配置里的BUILD_TESTSOFF、BUILD_PERF_TESTSOFF显式写出来再重新编译。OpenCV 默认会编译一部分测试用例虽然不算特别多但也能省不少时间。如果连 contrib 模块也用不上可以把OPENCV_EXTRA_MODULES_PATH去掉能显著缩短编译时间。不过我还是建议保留 contrib毕竟很多实用功能都在里面。7. 进阶为相机雷达联合标定等任务做准备7.1 为什么标定工具对 OpenCV 版本敏感热词里有人搜ubuntu18.04 安装 autoware 相机雷达联合标定工具这类工具在编译时对 OpenCV 的依赖非常敏感。标定流程本质上是把相机图像里的特征和激光雷达点云投影到同一坐标系OpenCV 负责相机内参标定、畸变矫正、特征提取与匹配。如果 OpenCV 版本不对或者 contrib 模块缺失像 aruco、fisheye、features2d 这些接口就可能找不到标定程序直接编译不过。我给一个实际建议如果你是为了标定工具才装 OpenCV那源码编译时一定确保opencv_aruco、opencv_features2d、opencv_calib3d、opencv_ximgproc这些模块都在编译列表里。CMake 配置完成后在输出里搜一下To be built看一下有没有对应的opencv_contrib_*模块。7.2 编译 contrib 模块的注意事项contrib 模块不是越多越好。编译更多模块意味着更长的编译时间和更大的库体积。对于标定场景核心模块其实就几个。如果你不确定需要哪些可以只保留aruco、xfeatures2d、features2d相关的其他模块在 CMake 阶段用BUILD_opencv_*显式关闭进一步缩短编译时间。还有一种做法是单独编译 contrib 中需要的模块而不是全部编译。但这需要你对 OpenCV 的构建系统比较熟悉新手不建议尝试。新手最快的方式就是全部一起编译反正一次装好后面不用再折腾。7.3 多版本共存与备份建议如果你机器上已经有一个 apt 版的 OpenCV 3.2又需要 OpenCV 4.5最好不要卸载老的因为有些系统工具依赖它。正确方式是把新版本安装到/usr/local编译项目时通过 CMake 指定版本。如果不想让两个版本冲突也可以在编译时把CMAKE_INSTALL_PREFIX指向独立目录比如/opt/opencv445然后通过环境变量切换。最后提一个建议在装 OpenCV 之前最好给系统留一份干净的备份或快照。这不是开玩笑我遇到过编译依赖装到一半apt 包损坏最后只能恢复系统的情况。如果手上没备份重装系统再配一次环境时间成本翻倍。本篇教程写的这些配置建议存成 build.sh 脚本下次重装直接跑能省很多重复工作。