GLIBCXX_3.4.x not found 解决方案
这个问题通常和 libstdc++ 版本有关。我的情况最开始出现在 Python 版 OpenCV 上,因此可以先尝试重新安装 Python 版 OpenCV:
pip install opencv-python
需要注意,pip install opencv-python 主要解决的是 Python OpenCV 包缺失、版本冲突或 wheel 依赖问题,不一定能解决系统 libstdc++ 缺少 GLIBCXX_3.4.x 符号的问题。
如果上面的方法不能解决,可以尝试更新系统的 libstdc++6:
sudo apt-get install libstdc++6
如果系统源里的版本仍然不够新,就需要进一步检查当前程序加载的是哪个 libstdc++.so.6,以及它是否来自系统路径、conda 环境或其他手动安装路径。
ARM 架构的 Jetson 设备找不到 v4l2_xxxx
平台:天准 Jetson AGX Orin。
编译时报错:
/usr/local/lib/libavcodec.so: undefined reference to `v4l2_open'
根据 NVIDIA 论坛中关于 libavcodec.so: undefined reference to v4l2_open 和 Jetson TX2 and FFmpeg - Can't initialize nvrm channel 的讨论,这类问题看起来和 FFmpeg 的安装或链接有关。但实际检查时,系统中 FFmpeg 是已经安装的。
通过 jtop 命令可以看到,当前系统中的 OpenCV 不支持 CUDA。这里需要注意,CUDA 支持和 FFmpeg / GStreamer 支持是 OpenCV 的不同编译选项,不能只根据 CUDA 支持情况直接判断 FFmpeg 是否启用。更准确的办法,是查看 OpenCV 编译日志,或者在代码中打印:
std::cout << cv::getBuildInformation() << std::endl;
很多 Jetson 设备出厂环境中的 OpenCV 不一定会开启 CUDA、FFmpeg 或 GStreamer 支持。如果 C++ 工程需要使用自己编译的 OpenCV,可以在 CMakeLists.txt 中指定 OpenCV 路径。知乎文章 Jetson Xavier NX OpenCV 安装 中提到的办法是卸载 OpenCV 并重装,这个方法没问题,但不一定必须这样做。
对于 C++ 工程,通常只需要修改 CMakeLists.txt 中的OpenCV_DIR,让它指向自己编译的 OpenCV 的 build 或安装后的 CMake 配置目录。至于 Python 版本的 OpenCV,可以后续在 conda 虚拟环境中单独配置。
于是我直接下载了 OpenCV 4.5.4 的 source 和 contrib 源码,并重新编译。这里选择 OpenCV 4.5.4 主要是为了兼容当前 JetPack / CUDA / 项目环境,而不是说 Jetson Orin 的 CUDA 11.x 一定不支持 OpenCV 4.7.0+。编译完成后,将 CMakeLists.txt 中的OpenCV_DIR 改为新编译 OpenCV 对应的路径。
修改后,不再报错。
GStreamer 警告:module avidemux0 reported: Internal data stream error
这个问题发生在使用 OpenCV 读取视频或者相机图像时,症状就是打不开图像。
一开始我以为是 OpenCV 缺少 GStreamer 相关支持,因此认为在 build 的时候设置下面这个选项应该能够解决:
-D WITH_GSTREAMER=ON
但是事实证明,添加 GStreamer 以后依旧不能打开图像。于是我开始怀疑问题出在 FFmpeg 支持上,需要确认 FFmpeg 是否被 OpenCV 正确识别。这个可以从 OpenCV 编译结果中看到。起初我的 OpenCV 编译结果是这个样子的:
-- Video I/O:
-- DC1394: NO
-- FFMPEG: NO
-- avcodec: YES (58.18.100)
-- avformat: YES (58.12.100)
-- avutil: YES (56.14.100)
-- swscale: YES (5.1.100)
-- avresample: NO
-- v4l/v4l2: YES (linux/videodev2.h)
可以看到,FFMPEG 的选项为NO。导致这种情况的原因比较多,可能是 pkg-config 没有找到 FFmpeg,也可能是版本不匹配、头文件路径不完整、库路径不完整,或者 CMake 的链接测试没有通过。
虽然在 terminal 中输入 ffmpeg 能够正确显示版本,但这只能说明命令行工具可用,不代表 OpenCV 编译时一定能正确找到 FFmpeg 的开发文件和依赖链。因此,我决定卸载并重新安装 FFmpeg。
在 jocover/jetson-ffmpeg 仓库中,有手动编译 FFmpeg 的方法。
在 patch ffmpeg and build 这个步骤中,git apply ffmpeg_nvmpi.patch 命令只需要运行一次。多次运行会报错,报错可以忽略。
随后,./configure --enable-nvmpi 也可能报错:
nvmpi not found
如果当前项目不需要通过 nvmpi 使用显卡解码视频,可以先去掉后面的--enable-nvmpi。
nvmpi 的作用是让 FFmpeg 能够通过 GPU 做视频解码,但我们的 GPU 更多用于推理,所以这里先不处理它。
针对编译时出现的报错,像是编译过程中某些静态库出现了问题,可以在编译 FFmpeg 的时候增加下面两个选项:
--disable-static
--enable-shared
注意,这里的参数前缀必须是真正的两个英文短横线 --,不要写成排版后的破折号。
另外,在原本 GitHub 仓库中的 README.MD 指南基础上,编译完 FFmpeg 后,还要执行安装:
sudo make install
参考文章
[1] GLIBCXX_3.4.20 not found, how to fix this error?
[2] Libavcodec.so: undefined reference to v4l2_open
[3] Jetson TX2 and FFmpeg - Can't initialize nvrm channel
评论