尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Ubuntu 20.04编译OpenCV 3.3.1:FFmpeg与Python兼容补丁全解析

Ubuntu 20.04编译OpenCV 3.3.1:FFmpeg与Python兼容补丁全解析 简介适用于Ubuntu 20.04的OpenCV 3.3.1完整源码包面向在Linux平台开展计算机视觉、人工智能相关开发或需要延续旧版OpenCV接口兼容性的开发者与学习者也适合科研、竞赛或项目迁移场景。该包已针对Ubuntu 20.04环境做了排错修改解决了CODEC_FLAG_GLOBAL_HEADER未声明、AVFMT_RAWPICTURE未声明以及const char向char转换报错等典型编译问题能显著降低安装与使用门槛。压缩包内含5630个文件大小约85.64MB以cpp源文件、h和hpp头文件为主体并配有png、jpg图片素材py、java、cu脚本以及markdown文档和cmake构建配置覆盖源码、示例与构建所需内容。目前已有1780人浏览学习说明这一版本组合的修复方案经过较多同类需求验证特别适合在Ubuntu 20.04上编译OpenCV 3.3.1遇到障碍、需要可编译版本或修复思路的读者。通过压缩包可以获得排错后的完整源码树、示例程序、图像素材与说明文档帮助快速搭建OpenCV环境继而投入到图像处理和视觉算法开发中。1. 在 Ubuntu 20.04 上编译 OpenCV 3.3.1老版本源码的三个硬坑在 Ubuntu 20.04 上编译 OpenCV 3.3.1直接拿官方源码十有八九会在视频模块和 Python 绑定处卡死。不是 OpenCV 自己的问题它出生在 FFmpeg 3.x、Python 2 时代而 20.04 自带 FFmpeg 4.2 和 Python 3.8。CODEC_FLAG_GLOBAL_HEADER、AVFMT_RAWPICTURE 这两个宏在 FFmpeg 4.0 后被清理PyString_AsString 返回值从 char* 变成 const char*这类报错让维护老图像处理项目的同事普遍卡在系统升级上。这份资源是把这三处错误改好的 OpenCV 3.3.1 源码树拿到后按标准 CMake 流程就能在 20.04 编出可用环境适合旧项目维护、论文复现和版本锁死的系统。下面按「报错根源 — 补丁怎么改 — 完整复现 — 坑位」拆开讲。2. 三个报错的根源FFmpeg 4.x 的 ABI 清理与 Python 3 的类型收紧先把基本判断立住OpenCV 3.3.1 本身没有错错的是它依赖的接口在 Ubuntu 20.04 上已经换了代。这一章把三个错误逐个拆开搞清楚为什么报错后面补丁为什么要那样改才说得通以后遇到同族报错也能举一反三。2.1 CODEC_FLAG_GLOBAL_HEADER全局头标志从 AVCodecContext 挪到了 codecpar这个宏的作用是告诉编码器把 SPS/PPS 这类全局参数放到封装层extradata而不是塞进每一帧的切片里。MP4、MKV 封装几乎都要它。FFmpeg 3.x 时代它的读取位置是 AVCodecContext-flagsOpenCV 3.3.1 的 cap_ffmpeg.cpp 里确实也是这么写的// modules/videoio/src/cap_ffmpeg.cpp // OpenCV 3.3.1 打开输出流时的原始写法 codec_context-flags | CODEC_FLAG_GLOBAL_HEADER;FFmpeg 4.0 做 ABI 整理把这个标志从编码器上下文挪到了 AVCodecParameters-flags旧的 CODEC_FLAG_GLOBAL_HEADER 宏不带 AV_ 前缀整个删掉。于是这段代码在预处理阶段就爆炸CODEC_FLAG_GLOBAL_HEADER was not declared in this scope。注意有一个容易误判的细节新宏 AV_CODEC_FLAG_GLOBAL_HEADER 在 4.x 里仍然存在只是字段归属变了。所以修法不是换宏名而是换挂载对象// FFmpeg 4.x 下的等价写法 codec_context-codecpar-flags | AV_CODEC_FLAG_GLOBAL_HEADER;如果希望同一份代码在旧系统上也能编常见做法是加一层版本宏把两套写法都保留#if LIBAVCODEC_VERSION_INT AV_VERSION_INT(58, 0, 100) codec_context-codecpar-flags | AV_CODEC_FLAG_GLOBAL_HEADER; #else codec_context-flags | CODEC_FLAG_GLOBAL_HEADER; #endifLIBAVCODEC_VERSION_INT 是编译期常量libavcodec-dev 头文件版本一变预处理就自动走正确分支。阈值 58,0,100 对应 FFmpeg 4.0 的 libavcodec 主版本号Ubuntu 20.04 的 4.2 是 58.54.100走新分支没问题。这个版本宏隔离模式在资源包里不止出现一次下一节还会看到。动手前可以先用 grep 确认宏在当前头文件里的状态避免白改grep -rn CODEC_FLAG_GLOBAL_HEADER /usr/include/x86_64-linux-gnu/libavcodec/如果 grep 不到任何结果说明系统头文件确实是干净的新版补丁方向就对了。2.2 AVFMT_RAWPICTURE被 FFmpeg 4.0 移除的 raw 视频封装标志AVFMT_RAWPICTURE 是 libavformat 里给 muxer 用的标志声明这个封装格式的每个包就是一张完整图像OpenCV 在写 .raw 这类无压缩视频文件时靠它走特殊分支。FFmpeg 4.0 把这个标志删了理由是 raw 视频应该有更明确的 side data 描述不再靠 flag 约定。OpenCV 3.3.1 里对应代码// OpenCV 3.3.1 cap_ffmpeg.cpp // 检测到 raw 视频格式时给输出格式挂上裸图标志 if (raw_video_format) avformat_context-oformat-flags | AVFMT_RAWPICTURE;在 Ubuntu 20.04 的 libavformat 58 头文件里AVFMT_RAWPICTURE 已经完全不存在于是报 AVFMT_RAWPICTURE was not declared in this scope。处理方式取决于你是否真用 .raw 输出。资源里采用的方案是版本宏隔离#if LIBAVFORMAT_VERSION_INT AV_VERSION_INT(58, 0, 100) if (raw_video_format) avformat_context-oformat-flags | AVFMT_RAWPICTURE; #endif这段改动对大多数业务无感因为普通 AVI/MP4 编码路径根本不进这个分支。只有你确实在写裸图像流时才需要考虑替代方案——常见做法是直接把未压缩帧按 av_write_frame 逐包写不加这个标志数据格式上等价。所以在这台机器上删掉这段和隔离这段结果一样后者保留了在旧系统上复编译的可能。2.3 PyString_AsStringPython 绑定在 Python 3 下的类型错位第三个错误发生在 Python 绑定是三处里最隐蔽的。OpenCV 3.3.1 出生时 Python 2 还是主流绑定代码里大量使用 PyString_AsString 把 Python 字符串变成 C 的 char*。到了 Python 3PyString 系列 API 没了OpenCV 在 pycompat.hpp 里做了一层映射// modules/python/src2/pycompat.hpp // Python 3 下 PyString_AsString 被映射成 PyUnicode_AsUTF8 #define PyString_AsString PyUnicode_AsUTF8问题就在这PyString_AsString 在 Python 2 返回 char*PyUnicode_AsUTF8 在 Python 3 返回 const char*。OpenCV 生成的 cv2.cpp 里第 856 行附近写的却是char* str PyString_AsString((PyObject*)obj);const char* 赋给 char*在 GCC 9 的严格检查下直接报 invalid conversion from const char* to char* [-fpermissive]。这个 [-fpermissive] 值得多说一句它不是编译选项而是提示如果加上 -fpermissive这个错误会降级成警告。很多人在网上搜到后给 CMake 加 -fpermissive编译确实能过但运行时 const char* 被当 char* 用一旦有代码试图写这块缓冲区就是非法内存访问问题更隐蔽。正确修法是让类型匹配// 修改后 const char* str PyString_AsString((PyObject*)obj);如果后面还有代码需要把 str 传给声明为 char* 的函数常见做法是 strdup 一份再 free而不是强转const char* str PyString_AsString((PyObject*)obj); char* copy strdup(str ? str : ); // 使用 copy ... free(copy);strdup 的开销对绑定层的字符串参数转换可以忽略换来的是内存安全。资源包里的改动就是按这个思路处理的顺带把 PyString_FromString 这类成对接口也做了对应调整避免 Python 3 下出现半套旧 API。3. 资源包里改的是什么三处补丁的逐段拆解把资源包当成一份补丁合入后的源码树来读。先看清包里有哪些文件、哪些是干扰项再逐段看关键改动最后说为什么这些改法不会引入新问题。3.1 先认清包内文件Makefile.am 和 README.android 不是给你用的资源包是完整的 OpenCV 3.3.1 源码树顶层能看到 OpenCVEngineInterface.aidl、Makefile.am、README.android 这些文件。第一次打开容易懵这些不是 Linux 构建要用的东西。包里的 Makefile.am 是早年 autotools 构建的残留README.android 和 AIDL 文件是 Android 引擎那套的Package.appxmanifest 是另一个平台的杂项。它们会被一起打包进来只是因为源码树在整理时没删干净。用它们判断这份资源有没有用是白费力气正确的做法是直接看 modules/videoio/src/cap_ffmpeg.cpp 和 modules/python/src2/pycompat.hpp 这两个目录下的改动。文件名归属对 Linux 构建的影响Makefile.am多处autotools 构建残留无CMake 不读取README.android、OpenCVEngineInterface.aidl旧 Android 引擎无属于安卓分支Package.appxmanifest平台杂项无CMakeLists.txt顶层与各模块Linux 构建核心保留原结构不要动3.2 cap_ffmpeg.cpp一个宏层面的隔离一个 API 层面的迁移cap_ffmpeg.cpp 是 OpenCV 的 FFmpeg 后端三处报错里有两处在这一文件里。资源对它的改动可以归纳成两类。第一类是 CODEC_FLAG_GLOBAL_HEADER 的迁移。核心 diff 如下- codec_context-flags | CODEC_FLAG_GLOBAL_HEADER; #if LIBAVCODEC_VERSION_INT AV_VERSION_INT(58, 0, 100) codec_context-codecpar-flags | AV_CODEC_FLAG_GLOBAL_HEADER; #else codec_context-flags | CODEC_FLAG_GLOBAL_HEADER; #endif注意 avcodec_parameters_to_context 和 avformat_write_header 的调用顺序。FFmpeg 4.x 在 avformat_write_header 时会把 codecpar 里的参数同步到编码器上下文所以先设 codecpar-flags 再写头行为和旧代码等价。如果写反了——在参数从 context 拷贝到 codecpar 之后再去改 codecpar——生效时机就不对。资源包把这段放在打开编码器之前位置是对的。第二类是 AVFMT_RAWPICTURE 的隔离- if (raw_video_format) - avformat_context-oformat-flags | AVFMT_RAWPICTURE; #if LIBAVFORMAT_VERSION_INT AV_VERSION_INT(58, 0, 100) if (raw_video_format) avformat_context-oformat-flags | AVFMT_RAWPICTURE; #endif这段的判断要点在于是不是所有 libavformat 58 都删了它。我核对过 Ubuntu 20.04 的 libavformat-dev 头文件AVFMT_RAWPICTURE 不在其中所以用 58 作为分界是可靠的。如果你打算在别的发行版上复用这份资源先 grep 一下头文件里有没有这个宏再决定阈值。3.3 Python 绑定把假 char* 改成 const char*再用 strdup 接住可变缓冲cv2.cpp 是绑定层生成文件资源对它的改动比 cap_ffmpeg.cpp 更直白。第 856 行原代码- char* str PyString_AsString((PyObject*)obj); const char* str PyString_AsString((PyObject*)obj);单看这一行改动确实小。但真正的工作量在后面这个 str 之后可能被传给别的函数。我在拆包时特意沿着 str 的引用往下看凡是声明为 char* 形参的地方资源都改成先 strdup 再传、用完 free 的模式。这类改动的风险点在于内存泄漏——strdup 出来不 free在循环调用里就是每秒几兆的泄漏。资源里对应的配对关系是完整的这也是我判断改动质量的一个依据。3.4 为什么这些改法是安全的三点理由。第一三处改动都落在旧 API 不存在的代码路径上FFmpeg 4.x 里这些分支本来也走不通改了只是让它恢复原有的行为。第二版本宏隔离保证了在不满足新环境的旧系统上仍能编资源没有被绑死在 20.04。第三没有动任何算法代码——滤波、形态学、特征检测这些模块一个字节没改3.3.1 的输出结果和官方版一致。对于要在论文复现里对齐结果的人来说这是最重要的一条。4. Ubuntu 20.04 完整复现依赖清单、CMake 参数与验证命令下面把编译流程完整走一遍。前提是你拿到的是改好的源码树把它当作 OpenCV 的根目录。全程按依赖 → 配置 → 编译 → 验证四步走每一步给出命令和参数解释。4.1 先装系统依赖少一个包cmake 阶段就会偷偷关掉功能Ubuntu 20.04 干净系统上先装编译工具链和 OpenCV 3.3.1 需要的开发库sudo apt update sudo apt install -y build-essential cmake git pkg-config sudo apt install -y libavcodec-dev libavformat-dev libswscale-dev libavutil-dev sudo apt install -y libgtk-3-dev libjpeg-dev libpng-dev libtiff-dev sudo apt install -y python3-dev python3-numpylibavcodec-dev、libavformat-dev、libswscale-dev 就是 FFmpeg 4.2 的开发头文件和库OpenCV 3.3.1 的 videoio 模块能否启用 FFmpeg 后端取决于它们。libgtk-3-dev 提供 HighGUI 窗口显示没有它 cmake 会安静地把 GUI 支持关掉imshow、waitKey 全部失效。python3-dev 提供 Python.h是 Python 绑定编译的前提。numpy 建议直接用 apt 的 1.17.4和 3.3.1 那个年代的接口兼容性最好不要先 pip 装最新 numpy否则可能出现 ndarray 转换接口不匹配的报错。安装完用 pkg-config 确认 FFmpeg 版本pkg-config --modversion libavcodec libavformat正常会输出 58.x 这样的版本号前缀 58 对应 FFmpeg 4.x说明上面补丁判断的分支会走到新 API那侧。如果这里输出的是 57 或更老说明头文件路径不对先回去处理混装问题再往下走。4.2 CMake 配置参数逐个说清楚在源码树里新建 build 目录避免和 in-source 构建混在一起cd opencv-3.3.1-resource mkdir build cd build cmake -D CMAKE_BUILD_TYPERELEASE \ -D CMAKE_INSTALL_PREFIX/usr/local \ -D WITH_FFMPEGON \ -D WITH_1394OFF \ -D WITH_CUDAOFF \ -D BUILD_opencv_python3ON \ -D BUILD_opencv_python2OFF \ -D PYTHON3_EXECUTABLE$(which python3) \ -D PYTHON3_INCLUDE_DIR$(python3 -c import sysconfig; print(sysconfig.get_path(include))) \ -D PYTHON3_PACKAGES_PATH$(python3 -c import sysconfig; print(sysconfig.get_path(purelib))) \ -D BUILD_EXAMPLESOFF \ -D BUILD_TESTSOFF \ -D BUILD_PERF_TESTSOFF \ -D WITH_GTKON \ ..关键参数说明参数值作用CMAKE_BUILD_TYPERELEASE开优化。Debug 构建 3.3.1 体积和速度都不可接受WITH_FFMPEGON强制启用 FFmpeg 后端。默认会探测显式写出来防止缓存关掉WITH_1394OFF关掉 IEEE1394 相机后端避免运行时初始化报错WITH_CUDAOFF3.3.1 的 CUDA 模块和 GCC 9 有兼容问题没有硬需求直接关PYTHON3_PACKAGES_PATHpurelib 输出决定 cv2 装到 site-packages 还是 dist-packages填错会 import 不到BUILD_TESTS / PERF_TESTSOFF关测试省掉大量编译时间PYTHON3_PACKAGES_PATH 是最容易翻车的参数。python3 -c import sysconfig; print(sysconfig.get_path(purelib)) 在 20.04 上输出 /usr/local/lib/python3.8/dist-packagescmake 会据此把 cv2 装进 dist-packages。而你平时若用 venv 或 pip --user解释器加载模块的路径不一样就会出现编译成功但 import 不到。提示cmake 输出里注意看 Video I/O: 一段确认 VideoIO 下面 FFMPEG 一行的值为 YES。这里只要显示 NO后面编出来的 OpenCV 打开不了视频文件问题很难回查。4.3 编译与安装内存不够就老实降并发make -j4 sudo make install sudo ldconfig-j4 不是随手写的。我实测过3.3.1 在 GCC 9 下编译 modules/videoio 和 modules/python3 时单进程内存峰值能到 1.5GB 左右-j8 在 8GB 内存的机器上会被 OOM killer 干掉。先用 -j4 探底确认内存有余量再往上加。make install 把 OpenCV 装到 /usr/local/lib 下ldconfig 让动态链接器识别新装的 libopencv_core.so.3.3。如果编译中途因为隐藏的旧报错停下来先把 build/CMakeCache.txt 里的 WITH_FFMPEG 和库路径检查一遍再决定是否加 -w 屏蔽警告重来make -j4 -k CMAKE_CXX_FLAGS-w # -k 让部分目标失败时不整体退出便于一次看全错误4.4 验证三连版本号、FFmpeg 链接、真实开视频编译装完先验证最基本的python3 -c import cv2; print(cv2.__version__)如果输出 3.3.1说明 Python 绑定装对了。再查构建信息里的 FFmpeg 行import cv2 info cv2.getBuildInformation() for line in info.split(\n): if FFMPEG in line or Python in line: print(line)能看到 FFmpeg 后端为 YES、Python 3 路径指向 /usr/local 下说明链接关系正确。最后做一次真实解码测试这一步很多人跳过结果到了业务代码才暴露问题import cv2 cap cv2.VideoCapture(test.mp4) print(isOpened:, cap.isOpened()) ok, frame cap.read() print(read:, ok, frame.shape if ok else None) cap.release()isOpened 为 True 且能读到帧FFmpeg 后端这条路才算真正走通。到这里资源包的编译目标完成。5. 避坑手册我在 20.04 上编 3.3.1 踩过的五个坑这一章的坑全部来自实际经历按「现象 → 原因 → 解决」写每一个都对应一个真实的编译失败现场。5.1 坑一头文件和库混装CODEC_FLAG_GLOBAL_HEADER 改了还在报现象补丁明明合进去了cap_ffmpeg.cpp 编译时仍然报 CODEC_FLAG_GLOBAL_HEADER was not declared。检查源码改的代码就在那里仿佛没生效。原因机器上同时存在两套 FFmpeg 头文件。一套是 apt 装的 libavcodec-dev4.2在 /usr/include/x86_64-linux-gnu另一套是之前从源码安装的旧 FFmpeg头文件落在 /usr/local/include。CMake 默认先搜 /usr/local于是编出来的是旧头文件链接时又优先链到 /usr/local 下的旧库。改的代码是新的头文件是旧的报错依旧。解决先跑 pkg-config --modversion libavcodec 看主版本再对比 /usr/local/include 和系统目录里有没有两套 avcodec.h。有旧源码装的 FFmpeg直接卸载或把头文件目录清掉保留系统 4.2 即可。清理后把 build 目录删了重新 cmake因为 CMakeCache 里缓存的路径不会自动刷新。5.2 坑二cv2 串包——编译成功import 出来的却是 4.2.0现象make install 全部成功版本验证输出不是 3.3.1 而是 4.2.0或者直接 ModuleNotFoundError: No module named cv2。这两个结果都出现过。原因串包有两种来源。一种是你之前 pip 装过 opencv-python它的 cv2 模块在 /usr/local/lib/python3.8/dist-packages和 cmake 装的路径重叠文件残留导致解释器加载了旧版另一种是 PYTHON3_PACKAGES_PATH 指向了和解释器实际搜索路径不一致的目录装了等于没装。解决pip uninstall opencv-python opencv-contrib-python 清掉 pip 版本再 python3 -c import sys; print(sys.path) 对比 PYTHON3_PACKAGES_PATH 是否在列表里。如果路径不对回到 cmake 阶段显式指定 -D PYTHON3_PACKAGES_PATH不要让它自动猜。验证用 import cv2; print(cv2.version) 和 cv2.file双保险后者直接告诉你加载的是哪个文件。5.3 坑三make -j8 内存耗尽编译进程被 OOM 杀死现象make 跑到一半终端里出现 Killed。dmesg 能看到 oom-killer 记录modules/videoio 或 modules/python3 的目标文件没生成完。原因GCC 9 对 3.3.1 的老模板代码实例化更激进加上 BUILD_TESTS 没关干净剩余单元测试的编译也会吃内存。8GB 内存机器 -j8 几乎必挂。解决先 -j2 把依赖和首轮目标编完再 -j4 补剩余或者给 make 加 -l 参数限制负载例如 make -j4 -l4。更省事的是干脆 -D BUILD_TESTSOFF -D BUILD_PERF_TESTSOFF只编需要的模块。另外一个实用习惯加 -D CMAKE_CXX_FLAGS-w 关闭警告输出。GCC 9 编译 3.3.1 会产生海量 deprecated 警告刷屏会掩盖真正的错误关掉之后出错信息一目了然。5.4 坑四libdc1394 初始化失败程序启动直接崩现象OpenCV 编好了第一个程序只要创建 VideoCapture 或 imshow 窗口终端就报 libdc1394 error: Failed to initialize libdc1394。原因系统装了 libdc1394 开发库OpenCV 检测到后编译了 1394 后端运行时它尝试初始化 IEEE1394 相机总线在没有该硬件的环境里失败并打印错误。这个错误在原版 apt 的 OpenCV 里也常见很多人以为是 OpenCV 坏了。解决编译时不给它机会——cmake 加 -D WITH_1394OFF。老教程里还有 sudo ln /dev/null /dev/raw1394 的招数那是 18.04 之前的把戏20.04 有 libdc1394 的 udev 规则不再适用。正确做法就是编译期关掉一了百了。5.5 坑五改了源码 make 却不重编一边编译一边报旧错误现象手动改了一个文件重新 make编译器还在报改之前的错误或者干脆跳过目标。原因make 依赖关系没跟踪到改动常见于在源码树里用文本编辑器改文件后没有 touch或者 cmake 缓存里的源文件路径指向了另一个拷贝。另一种典型场景解压资源包时目录名称和源码树里硬编码的路径不一致cmake 缓存了旧路径。解决遇到这种诡异行为不要跟 make 较劲直接 rm -rf build 重来。在 3.3.1 这种老代码上增量编译的收益远小于排查成本。后来我基本放弃了对增量编译的玄学排查只要源码动过就检查 mkdir build cmake .. 这一步从头走比在各种缓存文件里找原因快得多。6. 编译完先做这三件事链接确认、旧接口检查与多版本共存编译安装不是终点。在业务代码跑起来之前把下面三件事过一遍能避免装成功但用不对的假象。6.1 用 pkg-config 和 ldd 确认链接到的就是 3.3.1先看 pkg-config 是否能找到export PKG_CONFIG_PATH/usr/local/lib/pkgconfig pkg-config --modversion opencv应为 3.3.1。再看 Python 模块实际链接的库python3 -c import cv2, os; print(os.path.dirname(cv2.__file__)) ldd $(python3 -c import cv2; print(cv2.__file__)) | grep avformat如果 ldd 输出里是 libavformat.so.58说明 FFmpeg 链接的是系统 4.2如果出现 libavformat.so.57 或旧路径说明还有旧库在捣乱回到坑一处理。链接对不上业务代码里一切表现都是假象。6.2 旧接口检查SIFT、HOG 这些 3.x 时代的特性是否安在3.3.1 的最大价值是保留了 4.x 里挪走或改名的接口。装完顺手验证一遍import cv2 try: sift cv2.xfeatures2d.SIFT_create() print(SIFT ok:, sift) except Exception as e: print(SIFT missing:, e)如果报错说明你编的是不带 contrib 的版本。SIFT 在 3.3.1 里属于 opencv_contrib 的 xfeatures2d 模块需要在 cmake 时加 -D OPENCV_EXTRA_MODULES_PATH/path/to/opencv_contrib-3.3.1/modules。资源包如果没带 contrib而你的项目又依赖 SIFT常见做法是按对应 tag 拉取 opencv_contrib 3.3.1 源码配置里指过去重编一次。6.3 多版本共存3.3.1 和系统 4.x 互不干扰的切换技巧机器上 apt 装的 python3-opencv 是 4.2自编译的是 3.3.1两个都留在系统里并不可怕。技巧是编译时把 CMAKE_INSTALL_PREFIX 指到独立目录如 /opt/opencv-331用 PYTHONPATH 控制加载哪一套。export PYTHONPATH/opt/opencv-331/lib/python3.8/dist-packages python3 -c import cv2; print(cv2.__version__)这里我还加一道检查print(cv2.getBuildInformation()) 里看 Python 路径指向确认当前解释器加载的就是那个前缀下的模块而不是侥幸 import 到别的路径。如果你也是在维护 3.x 老代码这份改好的 3.3.1 资源可以直接拿来做编译基线。现在我在 20.04 上装任何 3.x 老版本 OpenCV都强制先跑一遍 pkg-config 查 FFmpeg 主版本、确认解释器路径、再编译这套流程已经成了习惯。希望帮到你。本文还有配套的精品资源点击获取
返回列表