Ubuntu 22.04 上 OpenCV 4.5 与 2.4 双版本共存编译与配置指南

发布时间:2026/7/27 14:32:02
Ubuntu 22.04 上 OpenCV 4.5 与 2.4 双版本共存编译与配置指南 1. 项目概述与核心需求解析在计算机视觉和图像处理领域OpenCV是一个绕不开的基石库。很多朋友在Ubuntu系统上折腾OpenCV时常常会遇到一个经典难题项目A依赖新版的OpenCV 4.x因为它提供了DNN模块、高效的CUDA加速等现代特性而项目B可能是一些遗留的老代码或者特定算法库又必须使用老旧的OpenCV 2.4.x版本因为其API接口甚至内部数据结构都发生了巨大变化。直接在系统里装一个版本必然会“打架”导致另一个项目无法编译或运行。我自己在接手一个涉及工业视觉检测和传统图像算法融合的项目时就深陷这个泥潭。所以今天要聊的就是如何在Ubuntu 22.04这个目前非常主流的LTS系统上同时安装OpenCV 4.5供C项目调用和OpenCV 2.4.13.7供C语言或老旧C项目调用让两个版本和平共处互不干扰。这个操作的核心价值在于“环境隔离”与“版本共存”。它不是简单地覆盖安装而是通过自定义编译安装路径/usr/local/opencv45和/usr/local/opencv2413和精心的系统配置让你在编译程序时可以像切换工具一样自由指定使用哪个版本的OpenCV。无论是用g、CMake还是Makefile都能清晰、无冲突地链接到正确的库文件。这对于需要维护多版本代码库的开发者、学生以及研究人员来说是一项非常实用的系统管理技能。接下来我会从准备工作、详细编译步骤、环境配置到最后的验证测试完整地走一遍这个流程并把过程中容易踩的坑和关键技巧都分享出来。2. 系统准备与依赖库安装在开始编译OpenCV之前确保你的Ubuntu 22.04系统处于一个健康且完备的状态是成功的第一步。这不仅仅是运行几条安装命令而是理解这些依赖项分别扮演什么角色避免后续编译报错时一头雾水。2.1 系统更新与基础构建工具首先打开终端更新软件包列表并升级现有软件。这能确保我们获取到最新的依赖库版本和安全性补丁。sudo apt update sudo apt upgrade -y接下来安装最核心的编译工具链。build-essential是一个元数据包它包含了gcc,g,make,libc-dev等编译C/C程序必不可少的基础工具。cmake则是OpenCV项目构建的指挥官我们后续的编译配置全靠它。pkg-config是一个辅助工具能帮助我们查询已安装库的编译和链接参数。sudo apt install -y build-essential cmake pkg-config注意即使你之前可能安装过gcc也建议通过build-essential再安装一次以确保所有相关的头文件和静态库都完整就位。2.2 图像I/O与视频处理依赖OpenCV需要依赖一些底层的库来处理不同格式的图像文件如JPEG, PNG, TIFF和视频流如从摄像头读取、视频文件编解码。这些依赖通常以-dev结尾的开发包形式提供。sudo apt install -y libjpeg-dev libpng-dev libtiff-dev sudo apt install -y libavcodec-dev libavformat-dev libswscale-dev libv4l-dev sudo apt install -y libxvidcore-dev libx264-devlibjpeg-dev, libpng-dev, libtiff-dev: 分别用于处理JPEG、PNG、TIFF格式的图像。没有它们imread()和imwrite()函数对相应格式的支持会受限或失效。libavcodec-dev等 (FFmpeg库): 这是处理视频的关键。libavcodec提供编解码器libavformat处理多媒体容器格式libswscale进行图像缩放和色彩空间转换。libv4l-dev是Video for Linux的库用于摄像头采集。libxvidcore-dev, libx264-dev: 是两种流行的视频编码器安装后OpenCV的VideoWriter可以用于生成XVID或H.264编码的视频文件。2.3 GUI、优化与其他功能依赖如果你需要用到OpenCV的图形界面功能如imshow显示窗口或者希望利用一些优化库提升性能还需要安装以下包。sudo apt install -y libgtk-3-dev sudo apt install -y libatlas-base-dev gfortran sudo apt install -y libtbb2 libtbb-dev sudo apt install -y python3-dev python3-numpylibgtk-3-dev: GTK图形界面工具库的开发文件。这是highgui模块在Linux下创建窗口的基础。如果不安装imshow()函数可能无法弹出显示窗口。libatlas-base-dev, gfortran: ATLAS是一个线性代数优化库gfortran是Fortran编译器。一些底层的数值运算尤其在OpenCV 2.4中可能会用到。libtbb-dev: Intel Threading Building Blocks库。这是一个用于并行编程的模板库OpenCV编译时开启TBB支持可以利用多核CPU加速某些算法。python3-dev, python3-numpy: 即使我们主要用C/C但OpenCV的构建系统默认会尝试编译Python绑定。安装这些可以确保编译过程顺利避免因找不到Python头文件而报错。如果你确定不需要Python接口可以在后续的cmake配置中通过-D BUILD_opencv_python2OFF -D BUILD_opencv_python3OFF显式关闭。实操心得依赖库宁多勿少。一次装全可以避免编译过程中途失败回头再来查找缺失的依赖那会非常耗时。上述列表是一个比较全面的集合涵盖了从基础到高级功能的常见需求。3. OpenCV 4.5.0 编译与安装我们将首先安装较新的OpenCV 4.5.0。选择从源码编译而不是安装预编译包核心目的是为了自定义安装路径实现版本隔离。3.1 源码下载与解压访问OpenCV官网的 Release页面 找到4.5.0版本。在终端中我们使用wget直接下载源码压缩包。cd ~ wget -O opencv-4.5.0.zip https://github.com/opencv/opencv/archive/4.5.0.zip unzip opencv-4.5.0.zipOpenCV 4.x版本通常还需要一个名为opencv_contrib的扩展模块它包含了许多额外的、不在主仓库的算法如SIFT、SURF等专利算法以及一些新型的DNN模块。如果你需要这些功能可以一并下载。这里为了演示核心流程我们仅编译主仓库。# 如果需要contrib模块执行以下命令 # wget -O opencv_contrib-4.5.0.zip https://github.com/opencv/opencv_contrib/archive/4.5.0.zip # unzip opencv_contrib-4.5.0.zip解压后你会得到一个opencv-4.5.0的目录。进入该目录并创建一个专门的构建目录build这是一个良好的习惯可以保持源码树的干净。cd opencv-4.5.0 mkdir build cd build3.2 CMake配置与关键参数解析接下来是最关键的步骤使用CMake生成构建文件。这里的参数决定了OpenCV将被如何编译以及安装到哪里。cmake -D CMAKE_BUILD_TYPERELEASE \ -D CMAKE_INSTALL_PREFIX/usr/local/opencv45 \ -D INSTALL_C_EXAMPLESOFF \ -D INSTALL_PYTHON_EXAMPLESOFF \ -D OPENCV_GENERATE_PKGCONFIGON \ -D BUILD_EXAMPLESOFF \ -D WITH_TBBON \ -D WITH_OPENMPON \ -D WITH_FFMPEGON \ -D WITH_GTKON \ -D BUILD_opencv_python2OFF \ -D BUILD_opencv_python3OFF \ ..逐条解释这些参数的意义-D CMAKE_BUILD_TYPERELEASE: 指定构建类型为发布Release模式。这会开启编译器优化如-O3生成的二进制文件运行速度更快但编译时间稍长且不便于调试。如果是开发调试可以设为DEBUG。-D CMAKE_INSTALL_PREFIX/usr/local/opencv45:这是实现多版本共存的核心。它指定了编译后的库文件、头文件等将被安装到的最终路径。我们将其设置为/usr/local/opencv45与系统默认的/usr/local区分开从而与后续安装的2.4.13.7版本隔离。-D OPENCV_GENERATE_PKGCONFIGON: 让CMake生成一个opencv4.pc文件。pkg-config工具可以通过这个文件轻松获取OpenCV 4的编译和链接标志如-I/usr/local/opencv45/include -L/usr/local/opencv45/lib -lopencv_core等这在后续编写Makefile或配置IDE时非常方便。-D WITH_TBBON和-D WITH_OPENMPON: 启用TBB和OpenMP多线程支持。现代CPU都是多核心的启用这些选项可以让OpenCV内部的一些算法自动并行化充分利用CPU资源显著提升性能。-D WITH_FFMPEGON和-D WITH_GTKON: 确保FFmpeg和GTK支持被启用这是我们之前安装相关依赖的目的。-D BUILD_EXAMPLESOFF: 关闭示例程序的编译可以大大加快编译速度。除非你需要参考这些例子否则建议关闭。-D BUILD_opencv_python2OFF -D BUILD_opencv_python3OFF: 因为我们专注于C/C调用所以关闭Python绑定的编译进一步节省编译时间。注意事项执行cmake命令后终端会输出大量的检查信息。请务必滚动查看末尾部分确保没有显示“NOT FOUND”的关键错误警告可以忽略一些。重点检查FFMPEG、GTK、Python等是否被正确找到并标记为“YES”。3.3 编译与安装配置成功后就可以开始编译了。使用make命令-j参数后面跟的数字表示并行编译的作业数通常设置为你的CPU核心数可以最大化利用硬件资源显著缩短编译时间。你可以用nproc命令查看核心数。make -j$(nproc)这个过程会持续较长时间半小时到数小时取决于机器性能。你可以去喝杯咖啡。编译完成后执行安装命令这将把编译好的库和头文件复制到之前指定的CMAKE_INSTALL_PREFIX路径下。sudo make install最后为了让系统动态链接器知道我们新安装的库在哪里需要更新一下链接库的缓存。虽然我们用了自定义路径但这一步对于确保某些依赖关系能被正确解析仍有帮助。sudo ldconfig至此OpenCV 4.5.0已经成功安装到了/usr/local/opencv45目录下。你可以通过ls /usr/local/opencv45查看里面的include和lib目录。4. OpenCV 2.4.13.7 编译与安装接下来安装较老的2.4.13.7版本。基本流程类似但细节上有些不同特别是2.4系列对较新的编译器和系统库可能有一些兼容性问题需要处理。4.1 源码下载与解压同样从GitHub Release页面下载2.4.13.7的源码。cd ~ wget -O opencv-2.4.13.7.zip https://github.com/opencv/opencv/archive/2.4.13.7.zip unzip opencv-2.4.13.7.zip cd opencv-2.4.13.7 mkdir build cd build4.2 解决潜在兼容性问题在Ubuntu 22.04上其自带的GCC编译器版本较高而OpenCV 2.4.13.7是一个较老的项目源码中可能使用了在新编译器下被视为错误或警告的旧式C语法。一个常见问题是与std::unary_function和std::binary_function相关这两个类在C17中已被移除。我们需要在编译时降低标准并忽略一些错误。此外一些视频编解码相关的包名在Ubuntu 22.04中可能发生了变化。因此在运行CMake之前最好先安装一个额外的兼容性包并检查相关依赖。# 安装一个可能缺失的兼容包 sudo apt install -y libtiff5-dev # 注Ubuntu 22.04中libjpeg-dev等已安装但确保其存在4.3 CMake配置与编译安装现在运行CMake注意安装路径改为/usr/local/opencv2413。cmake -D CMAKE_BUILD_TYPERELEASE \ -D CMAKE_INSTALL_PREFIX/usr/local/opencv2413 \ -D INSTALL_C_EXAMPLESOFF \ -D INSTALL_PYTHON_EXAMPLESOFF \ -D BUILD_EXAMPLESOFF \ -D WITH_TBBON \ -D WITH_OPENMPON \ -D WITH_FFMPEGON \ -D WITH_GTKON \ -D CMAKE_CXX_FLAGS-stdc11 \ ..这里多了一个关键参数-D CMAKE_CXX_FLAGS-stdc11。它强制编译器使用C11标准进行编译这通常能解决大部分因语法过时而导致的编译错误。C11是一个广泛支持且相对现代的标准能在兼容性和功能间取得较好平衡。配置完成后同样开始编译和安装。make -j$(nproc)在编译过程中你可能会看到一些关于“deprecated”的警告只要不是“error”导致编译停止都可以忽略。如果遇到因std::binary_function等导致的编译错误可能需要手动修改源码但使用-stdc11后这种情况在2.4.13.7中已很少见。编译完成后sudo make install sudo ldconfig现在第二个版本的OpenCV也安装完毕位于/usr/local/opencv2413。5. 多版本环境配置与使用两个版本的OpenCV已经静静地躺在各自的目录里了。接下来我们要解决如何让系统和我们自己知道怎么去使用它们。核心思想是不设置全局默认版本而是按需指定。5.1 理解pkg-config工具pkg-config是我们管理编译标志的得力助手。编译一个OpenCV程序时我们需要告诉编译器头文件在哪里找 (-I选项)。链接时库文件在哪里找 (-L选项)。需要链接哪些具体的库 (-l选项)。OpenCV的库有很多比如core,highgui,imgproc等手动写全这些参数很繁琐。pkg-config可以自动生成这些字符串。它通过读取.pc文件来工作。我们之前在编译OpenCV 4.5时通过-D OPENCV_GENERATE_PKGCONFIGON生成了opencv4.pc文件它通常位于/usr/local/opencv45/lib/pkgconfig/目录下。OpenCV 2.4默认也会生成一个可能是opencv.pc位于/usr/local/opencv2413/lib/pkgconfig/。为了让pkg-config能找到我们自定义路径下的.pc文件需要将这两个路径添加到PKG_CONFIG_PATH环境变量中。我们可以把这个设置写进shell的配置文件中如~/.bashrc或~/.zshrc这样每次打开终端都自动生效。echo export PKG_CONFIG_PATH/usr/local/opencv45/lib/pkgconfig:/usr/local/opencv2413/lib/pkgconfig:$PKG_CONFIG_PATH ~/.bashrc source ~/.bashrc添加后你可以用以下命令测试是否配置成功# 查询OpenCV 4.5的信息 pkg-config --cflags --libs opencv4 # 查询OpenCV 2.4的信息 (注意2.4的pc文件名通常是opencv而不是opencv4) pkg-config --cflags --libs opencv如果配置正确上述命令会分别输出两串不同的编译链接标志指向它们各自的安装路径。5.2 编写CMakeLists.txt调用不同版本CMake是现代C项目的主流构建工具。下面展示如何为两个不同版本的项目编写CMakeLists.txt。项目一使用OpenCV 4.5 (C)假设你的C源码文件为demo_cpp.cpp其CMakeLists.txt如下cmake_minimum_required(VERSION 3.10) project(OpenCV45_Project) # 设置C标准 set(CMAKE_CXX_STANDARD 11) # 关键步骤通过find_package查找OpenCV 4 # 指定PATHS参数让CMake到我们的自定义路径下寻找 find_package(OpenCV 4.5 REQUIRED PATHS /usr/local/opencv45 NO_DEFAULT_PATH) # 如果上面的find_package因版本号太具体而失败可以尝试更宽松的查找 # find_package(OpenCV 4 REQUIRED PATHS /usr/local/opencv45 NO_DEFAULT_PATH) # 或者使用pkg-config模式需系统已配置PKG_CONFIG_PATH # find_package(PkgConfig REQUIRED) # pkg_check_modules(OpenCV REQUIRED opencv4) message(STATUS OpenCV library status:) message(STATUS version: ${OpenCV_VERSION}) message(STATUS libraries: ${OpenCV_LIBS}) message(STATUS include path: ${OpenCV_INCLUDE_DIRS}) add_executable(demo_cpp demo_cpp.cpp) target_link_libraries(demo_cpp ${OpenCV_LIBS})项目二使用OpenCV 2.4.13.7 (C语言)假设你有一个用C语言写的源码demo_c.c它使用OpenCV 2.4的C接口函数和结构体通常以cv前缀开头如cvLoadImage。其CMakeLists.txt如下cmake_minimum_required(VERSION 3.10) project(OpenCV24_C_Project) # C语言项目设置C标准 set(CMAKE_C_STANDARD 99) # 查找OpenCV 2.4。注意CMake的包名可能仍是OpenCV但通过PATHS指定路径 find_package(OpenCV 2.4 REQUIRED PATHS /usr/local/opencv2413 NO_DEFAULT_PATH) # 同样如果版本指定失败可以尝试 # find_package(OpenCV REQUIRED PATHS /usr/local/opencv2413 NO_DEFAULT_PATH) message(STATUS OpenCV (C API) library status:) message(STATUS version: ${OpenCV_VERSION}) message(STATUS libraries: ${OpenCV_LIBS}) message(STATUS include path: ${OpenCV_INCLUDE_DIRS}) add_executable(demo_c demo_c.c) target_link_libraries(demo_c ${OpenCV_LIBS})关键技巧PATHS /usr/local/opencv...和NO_DEFAULT_PATH参数组合强制CMake只在指定路径下搜索OpenCV的配置文件避免了它找到系统其他位置可能存在的错误版本。5.3 使用GCC命令行直接编译对于简单的单文件测试直接用g或gcc配合pkg-config更快捷。编译调用OpenCV 4.5的C程序g -stdc11 demo_cpp.cpp -o demo_cpp pkg-config --cflags --libs opencv4编译调用OpenCV 2.4.13.7的C语言程序gcc demo_c.c -o demo_c pkg-config --cflags --libs opencv注意C语言程序链接时pkg-config返回的库列表是相同的因为OpenCV的C接口库包含在主要的共享库中。命令中的反引号用于执行pkg-config命令并将其输出的字符串作为参数插入到gcc/g命令中。6. 验证测试与常见问题排查安装和配置完成后必须进行验证确保两个版本都能正常工作。6.1 编写测试程序OpenCV 4.5 C 测试程序 (test_opencv45.cpp): 这个程序使用C APIcv::命名空间读取一张图片并显示。#include opencv2/opencv.hpp #include iostream int main() { // 使用OpenCV 4的C API cv::Mat image cv::imread(test.jpg); // 请确保当前目录下有一张名为test.jpg的图片 if(image.empty()) { std::cout Could not open or find the image! std::endl; return -1; } cv::imshow(Display window (OpenCV 4.5), image); cv::waitKey(0); return 0; }OpenCV 2.4.13.7 C 测试程序 (test_opencv24.c): 这个程序使用经典的C API函数以cv前缀开头完成同样的功能。注意C API中图像结构是IplImage*。#include opencv2/core/core_c.h #include opencv2/highgui/highgui_c.h #include stdio.h int main() { // 使用OpenCV 2.4的C API const char* filename test.jpg; IplImage* img cvLoadImage(filename, CV_LOAD_IMAGE_COLOR); if(!img) { printf(Could not open or find the image: %s\n, filename); return -1; } cvNamedWindow(Display window (OpenCV 2.4.13 C), CV_WINDOW_AUTOSIZE); cvShowImage(Display window (OpenCV 2.4.13 C), img); cvWaitKey(0); cvReleaseImage(img); cvDestroyWindow(Display window (OpenCV 2.4.13 C)); return 0; }6.2 编译与运行测试准备测试图片将一张名为test.jpg的图片放在与源代码相同的目录下。编译OpenCV 4.5测试程序g -stdc11 test_opencv45.cpp -o test45 pkg-config --cflags --libs opencv4编译OpenCV 2.4测试程序gcc test_opencv24.c -o test24 pkg-config --cflags --libs opencv运行测试./test45 ./test24如果两个程序都能成功弹出窗口显示图片那么恭喜你双版本OpenCV环境已经完美搭建成功6.3 常见问题与解决方案实录在实际操作中你可能会遇到以下问题。这里记录了我踩过的坑和解决方法。问题1CMake找不到OpenCV包。现象执行find_package(OpenCV REQUIRED)时CMake报错“Could not find a package configuration file provided by OpenCV”。原因CMake默认的搜索路径如/usr/local/share/OpenCV中没有找到OpenCVConfig.cmake文件。因为我们安装在了自定义路径。解决在find_package中显式指定PATHS参数如前面示例所示。或者在运行cmake命令时通过-D OpenCV_DIR/usr/local/opencv45/share/OpenCV变量直接告诉CMake配置文件的位置。问题2编译OpenCV 2.4时出现“undefined reference to std::binary_function...”等链接错误。现象make编译过程在链接阶段失败报错提到std::unary_function或std::binary_function未定义。原因这些是C98/03标准库中的组件在C17中被移除。Ubuntu 22.04的GCC默认可能使用更高的C标准。解决确保在CMake配置时添加了-D CMAKE_CXX_FLAGS-stdc11。如果还不行可以尝试修改有问题的源码文件但更简单的方法是直接使用一个稍旧的GCC版本如gcc-9但这可能引入其他兼容性问题不推荐首选。问题3运行程序时提示“error while loading shared libraries: libopencv_core.so.4.5: cannot open shared object file”。现象程序编译成功但运行时动态链接失败。原因系统动态链接器ld.so的缓存中没有记录我们自定义安装路径下的库文件位置。解决我们已经执行过sudo ldconfig。如果还不行可以检查/etc/ld.so.conf文件或/etc/ld.so.conf.d/目录下的配置文件确保包含了/usr/local/opencv45/lib和/usr/local/opencv2413/lib路径。然后再次运行sudo ldconfig。更直接的方法是在运行程序前临时设置LD_LIBRARY_PATH环境变量LD_LIBRARY_PATH/usr/local/opencv45/lib:$LD_LIBRARY_PATH ./test45问题4pkg-config找不到opencv或opencv4。现象执行pkg-config --cflags --libs opencv4返回“Package opencv4 was not found”。原因PKG_CONFIG_PATH环境变量没有正确设置或者.pc文件确实不存在。解决确认.pc文件是否存在ls /usr/local/opencv45/lib/pkgconfig/。确认PKG_CONFIG_PATH已包含该路径echo $PKG_CONFIG_PATH。如果路径正确但仍找不到可能是.pc文件名不叫opencv4.pc尝试用opencv.pc。可以用pkg-config --list-all | grep opencv查看所有可用的OpenCV相关包名。问题5imshow()窗口无法弹出或者程序运行后无显示。现象程序编译运行没有报错但图片窗口没有出现程序似乎卡住或直接结束。原因最常见的原因是GTK或GUI相关依赖没有安装好或者是在无图形界面的服务器终端SSH连接上运行。解决确保安装了libgtk-3-dev。如果你是在SSH远程连接需要开启X11转发ssh -X userhost并且本地有X Server在运行如Windows下的Xming、VcXsrv或WSL2的GUI支持。作为测试可以尝试使用cv::imwrite(“output.jpg”, image)将图片保存到文件看是否能成功以排除是否是图像读取的问题。整个流程下来虽然步骤不少但每一步都有其明确的目的。成功的关键在于细心和耐心尤其是在CMake配置和解决编译错误阶段。一旦环境搭建成功你就可以在一个系统上从容应对不同年代的OpenCV项目了。我个人最深的体会是永远不要盲目复制粘贴命令理解每一条命令背后的“为什么”才能在遇到问题时快速定位和解决。对于这种多版本共存的场景清晰的路径规划和环境变量管理是保持系统整洁和项目稳定的基石。