46

我首先使用这个脚本从源代码安装了 openCV 。当我测试时,它运行良好。

在我安装ROS kinetic并打开python3并运行import cv2后,出现以下错误:

Python 3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: /opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so: undefined symbol: PyCObject_Type
4

12 回答 12

33

看起来这个问题是由 ROS 添加/opt/ros/kinetic/lib/python2.7/dist-packages到 python 路径引起的。这实际上是在您使用命令激活 ROS 时发生的source /opt/ros/kinetic/setup.bash。此行通常添加在 bashrc 文件的末尾,在/home/username/.bashrc.

一种解决方法是从 bashrc 文件中删除这一行。这样,python3 opencv 包将被正确使用,并且您仍然可以运行source /opt/ros/kinetic/setup.bash以使用 ROS。但是,这确实意味着您不能在同一环境中使用 ROS 和 python3。

希望有人能想出一个更好的答案,但这应该在那之前有效。

于 2017-04-19T15:30:27.627 回答
20

如果您正在使用 anaconda,请激活您想要工作的环境,并从sys.path.

为此,请打开一个 python3 控制台,从中:

>>> import sys
>>> print(sys.path)

您将看到几条路径,其中您应该注意:

'/opt/ros/kinetic/lib/python2.7/dist-packages'

然后删除它:

>>> sys.path.remove('/opt/ros/kinetic/lib/python2.7/dist-packages')

使用本地编译的 opencv 在 anaconda3 上使用 python3.5 进行测试。这可能也适用于virtualenvs

对于永久解决方案,请删除@Paul 的回答中提到的'/opt/ros/kinetic/lib/python2.7/dist-packages'路径~/.bashrc

于 2018-02-09T12:12:00.267 回答
13

正如所指出的,您的source /opt/ros/kinetic/setup.bash命令将.bashrc其修改PYTHONPATH为:

> echo $PYTHONPATH
/opt/ros/kinetic/lib/python2.7/dist-packages

在我的例子中,由于我在我的 Python 3 项目中使用了 virtualenv,我只运行了以下命令来清除PYTHONPATH变量,同时激活了 virtualenv。

unset PYTHONPATH

现在,cv2在 Python 3 virtualenv 中导入可以干净地工作。我验证了路径cv2

In [1]: import cv2
In [2]: cv2.__file__
Out[2]: '<path_to_virtualenv>/lib/python3.5/site-packages/cv2/cv2.cpython-35m-x86_64-linux-gnu.so'

为了避免每次激活该 virtualenv 时都必须运行此命令,我将其添加到/bin/activatevirtualenv 目录中的文件中,如下所示:

...
# unset irrelevant variables
deactivate nondestructive

unset PYTHONPATH

VIRTUAL_ENV="/home/kaiyuzh/pyenv/py3"
export VIRTUAL_ENV
...
于 2019-06-19T13:11:03.377 回答
9

遇到了完全相同的问题。问题是 ROS 为 python 2 创建了它自己的 cv2.so 文件,然后将每个导入请求路由到该文件。这是一个非常简单的修复:

转到您的站点包文件夹

cd /usr/local/lib/python3.5/site-packages/

请注意,如果您使用的是虚拟环境,则必须在其中,并且应该执行以下操作:

cd ~/.virtualenvs/cv/lib/python3.5/site-packages/

然后,这次使用 -f 标志强制一个新的符号链接

ln -sf /usr/local/lib/python3.5/site-packages/cv2.so cv2.so

那应该可以解决问题!

于 2017-08-09T21:08:03.907 回答
6

如果这些解决方案都不适合您(如我的情况),您仍然可以尝试欺骗您的系统导入正确的 opencv

ros_path = '/opt/ros/kinetic/lib/python2.7/dist-packages'

if ros_path in sys.path:

    sys.path.remove()

import cv2

sys.path.append('/opt/ros/kinetic/lib/python2.7/dist-packages')

也许你可能会考虑在导入 cv2 之后在正确的位置替换 ros python 路径。

似乎我的 python 在导入正确的 cv2 时遇到了问题,即使路径设置正确,可能是因为与 cv2 相比,python3 cv2 库 (cv2.cpython-35m-x86_64-linux-gnu.so) 的命名很奇怪。所以我在 /opt/ros/kinetic/lib/python2.7/dist-packages

于 2018-08-02T11:20:05.963 回答
5

Step1:找到你的cv2.so的安装路径(如果你使用python-cv轮子安装opencv)

Step2:将路径导出到您的 .bashrc 或 .zshrc 文件,如下所示:

export PYTHONPATH="/home/userx/anaconda3/lib/python3.5/site-package‌​s:$PYTHONPATH"

感谢@lxrd-aj

于 2017-09-08T14:59:15.113 回答
4

我试图删除/opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so. 现在它正在工作。

于 2018-01-27T16:55:09.440 回答
2

其实我也遇到这个问题。我只是注释掉了来源:

/opt/ros/kinetic/setup.bash

然后,打开终端,在我执行的 anaconda lib 路径中:

sudo ln -sf /home/apg/miniconda3/lib/python3.6/site-packages/cv2.so /opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so

/home/apg/miniconda3是我的 python3 的安装/opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so路径,opencv-python是安装的路径。

我还不知道为什么这个命令有效,但它确实为我解决了我以前无法导入 cv2 的问题。

于 2017-12-31T19:47:58.210 回答
2

在 ROS 设置运行期间/opt/ros/kinetic/setup.bash,其他东西之间的脚本将转到 python2 和 python3 的每个分发包,并将其添加到 python 系统路径。当您尝试cv2使用 python3 导入时,它将首先找到路径中包含的 Python2 的 cv2 绑定。

如果您根本不打算为您的 ROS 项目使用 python2.7,请考虑完全删除 python2.7 OpenCV 包,以便在运行 ros 设置脚本时不会将其添加到路径中:

$ rm /opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so

如果您计划同时使用两个 Python 版本,另一种更温和的方法是创建两个具有正确绑定的虚拟环境,并根据您的要求激活一个或另一个。

于 2018-09-10T02:14:04.753 回答
1

类似的问题在这里。正如其他人所建议的那样,在变量/opt/ros/kinetic/setup.bash中附加到 ROS opencv 的路径。PYTHONPATH

如果您正在使用多个virtualenvs 并且您需要一个适用于大多数情况的解决方案,那么您可以将以下代码片段放入您的.bashrc:

source /opt/ros/kinetic/setup.bash
array=( $(find ~/.virtualenvs/ -mindepth 1 -maxdepth 1 -type d) )

for i in "${array[@]}"
do
  export PYTHONPATH="$i/lib/python2.7/site-packages:$PYTHONPATH"
done

所以想法是,如果你有一个集中的所有virtualenvs 目录(例如,当你使用 时virtualenvwrapper),我们可以使用以下方法搜索这些目录:

$(find ~/.virtualenvs/ -mindepth 1 -maxdepth 1 -type d)

鉴于我们所有的virtualenvs 都在~/.virtualenvs. 这应该给我们一个我们所有virtualenv的根目录的列表。

然后,我们循环遍历 virtualenv 目录数组,并将它们的路径(例如~/.virtualenvs/testenv/lib/python2.7/site-packages)附加到PYTHONPATH. 请注意,这应该source /opt/ros/kinetic/setup.bash.

这不是问题的完美解决方案,因为如果两个 env 具有不同的 opencv 版本,您仍然会发生冲突,但对于最初的问题,至少它应该可以工作。

或者,您可以手动对所需的 virtualenv 执行相同的技巧:

export PYTHONPATH=~/.virtualenvs/testenv/lib/python2.7/site-packages:$PYTHONPATH
于 2018-11-28T18:26:46.833 回答
0

您可以暂时删除ROS PATHimport cv2.

这是我处理该问题的解决方案:

try:
    import cv2
except ImportError:
    import sys
    ros_path = '/opt/ros/kinetic/lib/python2.7/dist-packages'
    sys.path.remove(ros_path)
    import cv2
    sys.path.append(ros_path)
于 2021-07-20T21:04:45.310 回答
0

我之前在 Ubuntu 16.04 上安装了 ROS 和 catkin_tools,突然遇到了同样的问题。修复它的工作如下:

  1. 导航到主目录
  2. 在编辑器中打开(通常默认情况下此文件是隐藏的;如果是,请按+.bashrc使其可见)ctrlh
  3. 注释掉或删除这两行source /opt/ros/kinetic/setup.bashsource ~/catkin_ws/devel/setup.bash#通过在两条相应的行前面放置一个来注释掉作品。
  4. 保存存档
  5. 重启电脑

完毕。

于 2019-12-30T16:14:58.867 回答