首页 > 解决方案 > 为什么我在 python3.7.3 上运行时会收到 opencv2 的 ImportError?

问题描述

我正在尝试在 Mac OS 10.10 上使用 python3.7.3 导入 o​​pencv2,但发生 ImportError。我该如何解决?

我尝试使用 pip、pip3 和 homebrew 安装 opencv3。可能没有正确安装。

import cv2
import numpy as np
import sys
import pytesseract as py
import matplotlib.pyplot as plt

错误

Traceback (most recent call last):
  File "/Users/wujian/Desktop/Project/Proj.py", line 1, in <module>
    import cv2
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/cv2/__init__.py", line 3, in <module>
    from .cv2 import *
ImportError: dlopen(/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/cv2/cv2.cpython-37m-darwin.so, 2): Symbol not found: _clock_gettime
  Referenced from: /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/cv2/.dylibs/libavutil.56.22.100.dylib (which was built for Mac OS X 10.12)
  Expected in: /usr/lib/libSystem.B.dylib
 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/cv2/.dylibs/libavutil.56.22.100.dylib

标签: python-3.xmacosopencv

解决方案


这个问题似乎(奇怪地)与您的libavutil副本有关,它是ffmpeg的一部分。

这部分错误消息暗示了这一点:

ImportError: dlopen(/.../cv2/cv2.cpython-37m-darwin.so, 2): Symbol not found: _clock_gettime
  Referenced from: /...python3.7/site-packages/cv2/.dylibs/libavutil.56.22.100.dylib (which was built for Mac OS X 10.12)

安装OpenCV需要ffmpeg。如果您通过 homebrew安装它,它会被列为依赖项。

$ brew info opencv
...
==> Dependencies
Build: cmake ✓, pkg-config ✓
Required: eigen ✓, ffmpeg ✓, glog ✓, ...

安装ffmpeg将包含libavutil库,可以通过下载预构建的共享库Homebrew来检查:

$ brew list ffmpeg | grep libavutil.*dylib
/usr/local/Cellar/ffmpeg/4.1.4_1/lib/libavutil.56.22.100.dylib
/usr/local/Cellar/ffmpeg/4.1.4_1/lib/libavutil.56.dylib
/usr/local/Cellar/ffmpeg/4.1.4_1/lib/libavutil.dylib

现在,您的问题是系统上的libavutil(和ffmpeg)与您的 Mac 10.10 不向后兼容。它是针对较新的 Mac 10.12 构建的,它似乎已经对clock_gettimeAPI 进行了更改,导致“未找到符号”错误。这也已报告给opencv-python 问题

这与 OpenCV 无关。该错误来自通过自制软件安装的 libavutil (=FFmpeg)。该错误与二进制向后兼容性有关(显然 Apple 已更改 libsystem 接口)。我对 Apple 的生态系统不太熟悉,但如果在最新的操作系统版本中也存在旧符号,则针对早期操作​​系统版本构建 FFmpeg 可能会解决问题。在 macOS 上完全向后兼容可能无法实现。


我只是在嵌套依赖关系的深处被这个问题所困扰;FFmpeg 的目标是 10.12,但我在 10.11。希望尽快出一个固定版本。

请注意,虽然降级 Xcode 也可能有效,但针对 macOS 早期版本的正确方法是将例如 -mmacosx-version-min=10.11 或 -mmacosx-version-min=10.6 添加到 CFLAGS/CXXFLAGS/LDFLAGS; 这将调整标头、编译器和链接器,以生成至少与该 macOS 版本兼容的二进制文件。

似乎唯一的解决方案是安装与您的 Mac 10.10 兼容的旧版本ffmpeg(带有libavutil),然后告诉 OpenCV 链接到该旧版本。您可能还需要从源代码构建 OpenCV(请参阅Configure and Build OpenCV to Custom FFMPEG Install)。

您也可以尝试在 SuperUser 上查看这篇文章:
我应该为 macOS 下载哪个 ffmpeg 包?


推荐阅读