После установки ROS Kinetic нельзя импортировать OpenCV

Сначала я установил openCV из источника, используя этот скрипт. Когда я тестировал, он работал хорошо.

После того, как я установил python3 ROS и открыл 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

Ответ 1

Похоже, эта проблема вызвана тем, что ROS добавляет /opt/ros/kinetic/lib/python2.7/dist-packages к python. Это действительно происходит, когда вы активируете ROS с source/opt/ros/kinetic/setup.bash команды source/opt/ros/kinetic/setup.bash. Эта строка часто добавляется в конец вашего файла bashrc в /home/username/.bashrc.

Обходной путь заключается в том, чтобы удалить эту строку из файла bashrc. Таким образом, python3 opencv-пакеты будут правильно использоваться, и вы все равно можете запустить source/opt/ros/kinetic/setup.bash для использования ROS. Однако это означает, что вы не можете использовать ROS и python3 из той же среды.

Надеюсь, кто-то может придумать лучший ответ, но это должно работать до тех пор.

Ответ 2

Если вы работаете с 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')

Протестировано с python3.5 на anaconda3 с локально скомпилированным opencv. Это, вероятно, применимо и к virtualenvs.

Для постоянного решения удалите путь '/opt/ros/kinetic/lib/python2.7/dist-packages' из ~/.bashrc как указано в ответе @Paul.

Ответ 3

Имел ту же самую проблему. Проблема в том, что ROS создает собственный файл cv2.so для python 2, а затем маршрутизирует каждый запрос на импорт в этот файл. Это довольно легко исправить:

перейдите в папку с вашими сайтами

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

И это должно исправить ситуацию!

Ответ 4

Шаг 1. Найдите путь, где установлен ваш cv2.so (если вы используете колесо python-cv для установки opencv)

Шаг 2. Экспортируйте путь к файлу.bashrc или.zshrc, как показано ниже:

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

Благодаря @lxrd-aj

Ответ 5

Я попытался удалить /opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so. Теперь он работает.

Ответ 6

На самом деле, я также сталкиваюсь с этой проблемой. Я просто прокомментировал источник:

/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.

Ответ 7

Если ни одно из этих решений не работает для вас (как и в моем случае), вы все равно можете попытаться обмануть вашу систему для импорта правильного 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')

Возможно, вы захотите заменить путь python ros в нужном месте после импорта cv2.

Кажется, что у моего python возникли проблемы с импортом правильного cv2, хотя путь был установлен правильно, вероятно, из-за странного наименования библиотеки cv2 python3 (cv2.cpython-35m-x86_64-linux-gnu.so) по сравнению с cv2. поэтому у меня есть /opt/ros/kinetic/lib/python2.7/dist-packages

Ответ 8

Во время установки ROS, запускающей /opt/ros/kinetic/setup.bash, сценарий между другими вещами будет передаваться в каждый дистрибутив для python2 и python3, и он добавит его в пул системы python. Когда вы пытаетесь импортировать cv2 с помощью python3, он сначала найдет привязку cv2 для Python2, как включенную в путь.

Если вы вообще не планируете использовать python2.7 для своего проекта ROS, подумайте об удалении полностью пакета OpenCV python2.7, поэтому он не будет добавлен к пути при запуске сценария установки ros:

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

Еще один более мягкий подход, если вы планируете использовать обе версии Python, - это создать две виртуальные среды с правильными привязками и активировать их в зависимости от ваших требований.

Ответ 9

Подобная проблема здесь. Как предлагали другие, /opt/ros/kinetic/setup.bash добавляет путь к ROS opencv в переменной PYTHONPATH.

Если вы работаете с несколькими virtualenv и вам нужно решение, которое будет работать в большинстве случаев, вы можете поместить следующий фрагмент кода в ваш .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

Таким образом, идея заключается в том, что если у вас есть централизованный каталог всех ваших virtualenv (например, когда вы используете virtualenvwrapper), мы можем искать эти каталоги, используя:

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

учитывая, что все наши virtualenv находятся под ~/.virtualenvs. Это должно дать нам список всех наших корневых каталогов virtualenv.

Затем мы перебираем массив каталогов virtualenv и добавляем их путь (например, ~/.virtualenvs/testenv/lib/python2.7/site-packages) в PYTHONPATH. Обратите внимание, что это должно быть сделано сразу после source/opt/ros/kinetic/setup.bash.

Это не идеальное решение проблемы, поскольку вы все равно можете получить конфликты, если два envs имеют разные версии opencv, но для первоначальной проблемы, по крайней мере, это должно работать.

Кроме того, вы можете просто вручную сделать тот же трюк для желаемого virtualenv:

export PYTHONPATH=~/.virtualenvs/testenv/lib/python2.7/site-packages:$PYTHONPATH

Ответ 10

Как уже указывалось, команда source/opt/ros/kinetic/setup.bash в вашем .bashrc изменяет PYTHONPATH:

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

В моем случае, поскольку я использую virtualenv для своих проектов на Python 3, я просто выполнил следующую команду, чтобы очистить переменную 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/activate activ в каталоге virtualenv следующим образом:

...
# unset irrelevant variables
deactivate nondestructive

unset PYTHONPATH

VIRTUAL_ENV="/home/kaiyuzh/pyenv/py3"
export VIRTUAL_ENV
...