After install ROS Kinetic, cannot import OpenCV
Asked Answered
P

12

48

I have first installed openCV from source using this script. When I tested it was working well.

After I installed ROS kinetic, and open python3 and run import cv2 as cv, got the following error:

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 as cv
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
Praxis answered 25/3, 2017 at 17:59 Comment(1)
Your python3 is trying to load a python2 module?! Can you run the following commands and paste the output into your question?: ldd /opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so, echo $PYTHONPATH, (in pythonconsole) import sys; print(sys.path),Squirmy
T
33

It looks like this problem is caused by ROS adding /opt/ros/kinetic/lib/python2.7/dist-packages to the python path. This actually happens when you activate ROS with the command source /opt/ros/kinetic/setup.bash. This line is often added at the end of your bashrc file, in /home/username/.bashrc.

A workaround is to remove this line from the bashrc file. This way the python3 opencv packages will be correctly used, and you can still run source /opt/ros/kinetic/setup.bash to use ROS. However, this does mean you cannot use ROS and python3 from the same environment.

Hopefully someone can come up with a better answer, but this should work until then.

Thrippence answered 19/4, 2017 at 15:30 Comment(2)
My workaround was not to delete the python path added by ROS but to append the one by anaconda to it e.g ` export PYTHONPATH="/home/userx/anaconda3/lib/python3.5/site-packages:$PYTHONPATH" `Dhole
Hi. I have commented the line from my bashrc file and also added sys.path.remove('/opt/ros/kinetic/lib/python2.7/dist-packages/') in my code. It doesn't show up when I print the paths but still causing trouble when I import cv2. Can you help?Comedietta
P
21

If you are working with anaconda, activate the environment you want to work from, and remove the culprit from sys.path.

To do so, open a python3 console, from which:

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

You will see several path, among which you should notice:

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

Then remove it:

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

Tested with python3.5 on anaconda3 with locally compiled opencv. This is likely applicable to virtualenvs as well.

For a permanent solution, remove the path '/opt/ros/kinetic/lib/python2.7/dist-packages' from ~/.bashrc as mentioned in @Paul's answer.

Pensile answered 9/2, 2018 at 12:12 Comment(4)
print(sys.path) instead of print('sys.path')Sideling
This is not a permanent solution as I need both ros and python3Laterality
@Laterality Why the downvote? The "permanent" solution originally provided by Paul's answer does allow the use of both ROS and python3. You can ask a new question for your specific problem or write a constructive comment so that you could get some help.Pensile
I do not find the line /opt/ros/kinetic/lib/python2.7/dist-packages in my ~/.bashrc script... it only sources these two files: source /opt/ros/kinetic/setup.bash source ~/catkin_ws/devel/setup.bash... Any idea where did ROS sneaks in and changes my sys.path? Thanks!Lupine
S
14

As pointed out, the source /opt/ros/kinetic/setup.bash command in your .bashrc modifies the PYTHONPATH to be:

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

In my case, since I am using a virtualenv for my Python 3 projects, I just ran the following command to clear the PYTHONPATH variable, while the virtualenv is activated.

unset PYTHONPATH

Now, importing cv2 in Python 3 virtualenv works cleanly. I verified the path of 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'

To avoid having to run this command every time I activate that virtualenv, I added it to the /bin/activate file in the virtualenv directory, as follows:

...
# unset irrelevant variables
deactivate nondestructive

unset PYTHONPATH

VIRTUAL_ENV="/home/kaiyuzh/pyenv/py3"
export VIRTUAL_ENV
...
Sake answered 19/6, 2019 at 13:11 Comment(1)
this was simple, yet great solution! Thanks.Leopoldine
B
9

Was having the exact same problem. The issue is that ROS creates it's own cv2.so file for python 2, and then routes every import request to that file. It's a pretty easy fix:

go to your site-packages folder

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

note, if you are using a virtual environment, you must be within that, and should instead do something like:

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

Then, force a new sym-link this time using the -f flag

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

And that should fix things!

Blondellblondelle answered 9/8, 2017 at 21:8 Comment(1)
Can I ask in the final line of code, what is the source and what is the destination? Is the source = virtual environment site packages, and where is the destination? Thanks..Lupine
L
7

If none of those solutions works for you (as in my case) you could still try to trick your system into importing the right opencv

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

if ros_path in sys.path:
    sys.path.remove()

import cv2 as cv

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

Maybe you might consider replacing the ros python path at the right location after importing cv2.

It seems that my python had problems importing the correct cv2 even though the path was set correctly, probably because of the weird naming of the python3 cv2 library (cv2.cpython-35m-x86_64-linux-gnu.so) compared to the cv2.so I have in /opt/ros/kinetic/lib/python2.7/dist-packages

Laterality answered 2/8, 2018 at 11:20 Comment(2)
Saved my day! Thanks.Whichsoever
Awesome! Great work :) On python 3.7 sys.path.remove() should be replaced with sys.path.remove(ros_path)Mackie
E
5

Step1: Find the path where your cv2.so is installed (if you use the python-cv wheel to install the opencv)

Step2: Export the path to your .bashrc or .zshrc file, just like this:

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

Thanks to @lxrd-aj

Exasperate answered 8/9, 2017 at 14:59 Comment(0)
E
4

I tried to remove /opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so. Now It is working.

Emission answered 27/1, 2018 at 16:55 Comment(0)
I
2

Actually, I also encounter this problem. I just commented-out the source:

/opt/ros/kinetic/setup.bash

and then, open the terminal, In the anaconda lib path I executed:

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 is the path where my python3 was installed, and /opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so was the path that opencv-python was installed.

I don't know yet why this command works, but it did work for me to solve the problem that I was not able to import cv2 previously.

Ingratiate answered 31/12, 2017 at 19:47 Comment(1)
And after I executed this,the cv2.so in /opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so has become a broken link.Ingratiate
I
2

During ROS setup running /opt/ros/kinetic/setup.bash, the script between other things will go to every distribution package for python2 and python3 and it will add it to the python system path. When you try to import cv2 using Python 3 it will first find the OpenCV binding for Python 2 as included in the path.

If you are not planning on using python2.7 at all for your ROS project, consider removing entirely the python2.7 OpenCV package, so it won't be added to the path when running the ros setup script:

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

Another more gentle approach if you are planning to use both Python versions would be to create two virtual environments with the correct bindings, and activate one or another depending on your requirements.

Invalid answered 10/9, 2018 at 2:14 Comment(1)
This worked for me. I am still able to import cv2 and rospy in both Python2 and Python3. Removing this simply means you have to use your own installed opencv, which can be done though pip.Espy
J
1

Similar problem over here. As others suggested, /opt/ros/kinetic/setup.bash appends a path to ROS opencv in the PYTHONPATH variable.

If you are working with multiple virtualenvs and you need a solution that will work in most of the cases, then you can put the following code snippet in your .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

So the idea is that if you have a centralised directory of all of your virtualenvs (e.g when you use virtualenvwrapper) we can search for those directories using:

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

given that all of our virtualenvs are under ~/.virtualenvs. This should give us a list of all of our virtualenvs root directory.

We are then looping over the array of virtualenv directories and we are appending their path (e.g ~/.virtualenvs/testenv/lib/python2.7/site-packages) to the PYTHONPATH. Note that this should be done just after the source /opt/ros/kinetic/setup.bash.

It's not a perfect solution to the problem as you can still get conflicts if two envs have different opencv versions, but for the initial problem, at least it should work.

Alternatively, you can just manually do the same trick for the desired virtualenv:

export PYTHONPATH=~/.virtualenvs/testenv/lib/python2.7/site-packages:$PYTHONPATH
Joyjoya answered 28/11, 2018 at 18:26 Comment(0)
R
0

I had previously installed ROS and catkin_tools on Ubuntu 16.04 and suddenly experienced the same issue. Fixing it worked as follows:

  1. Navigte to home directory
  2. Open .bashrc in editor (often this file is hidden by default; if so, make it visible by pressing ctrl + h)
  3. Comment out or remove the two lines source /opt/ros/kinetic/setup.bash and source ~/catkin_ws/devel/setup.bash. Commenting out works by putting an # in front of the two respective lines.
  4. Save file
  5. Restart PC

Done.

Rebbeccarebe answered 30/12, 2019 at 16:14 Comment(0)
G
0

You can temporarily remove the ROS PATH and import cv2.

Here's my solution to deal with that problem:

try:
    import cv2 as cv
except ImportError:
    import sys
    ros_path = '/opt/ros/kinetic/lib/python2.7/dist-packages'
    sys.path.remove(ros_path)
    import cv2 as cv
    sys.path.append(ros_path)
Gulp answered 20/7, 2021 at 21:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.