ImportError: /opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so: undefined symbol: PyCObject_Type

时间:2019-02-26
本文章向大家介绍ImportError: /opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so: undefined symbol: PyCObject_Type,主要包括ImportError: /opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so: undefined symbol: PyCObject_Type使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

问题描述:

Ubuntu16.04 安装了ROS Kinetic之后Python3不能import cv2

据了解在,python中是通过cv2.so调用opencv的库的:

  • Python调用opencv的原理是:opencv编译出共享库文件,python把这个共享库文件作为一个模块加载并使用。通俗点就是,编译opencv的时候开启python接口选项,编译好了会产生cv2.so(linux下)或者cv2.pyd(windows下)这个共享库文件,python代码中import这个cv2就可以用了。为了能正确import它,往往需要把cv2.so放在python找包能找到的路径下,或者修改PYTHONPATH环境变量让它包含cv2.so所在路径。

可以看出这个问题是由ROS添加/opt/ros/kinetic/lib/python2.7/dist-packages到python路径引起的。

当使用命令激活ROS时,实际上会发生这种情况source /opt/ros/kinetic/setup.bash。这行通常会添加到bashrc文件的末尾/home/username/.bashrc。

这样就可以正确使用python3 opencv包,你仍然可以运行source /opt/ros/kinetic/setup.bash使用ROS。但是,这确实意味着无法在同一环境中使用ROS和python3

就是说,在用python3运行opencv3 即import cv2的时候需要把.bashrc 或者 .zshrc中的有关ros的soure都注释掉,才可以正常运行

处理方法


(1)第一种方法 
需要在~/.bashrc文件中增加一行命令,操作步骤为:

cd ~
gedit .bashrc或者使用vim .bashrc
部分处理方法是在.bashrc文件中把source /opt/ros/kinetic/setup.bash添加#符号注释掉,但这样势必会造成再次使用ROS时又需要把注释#去掉,这确实意味着无法在同一环境中使用ROS和python3

就是说,在用python3运行opencv3 即import cv2的时候需要把.bashrc 或者 .zshrc中的有关ros的soure都注释掉,才可以正常运行。

因此查找相关的材料可以在打开的.bashrc文件中的最后增加如下一行:

export PYTHONPATH="/home/panda/.local/lib/python3.5/site-packages":$PYTHONPATH

注意:上面的路径中的panda需要换成你自己的用户名 
PYTHONPATH后的/home/panda/.local/路径内容需要根据自己的安装路径来来进行更改。但是最后得出的结果可能会和之前提到的那种方法产生一样,即运行ROS时需要注释掉这行代码,运行非ROS时需要加上这行代码。而接下来的第二种方法会在python文件中进行处理。

(2)第二种方法 
因为是受ROS安装的影响,ROS安装之后会在python pyth中加入:

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


而为了解决此问题,可以在需要运行的python文件(即使用import cv2的python文件)中,添加以下代码:

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

通过这两行代码可以把ROS写入path中的路径给清除,进行可以import anaconda中的cv2包。

注:通过此方法再次import cv2时,问题得以解决,不再报错,但此方法并不一定可以保证在所有的情况下都适用,但还是值得一试滴。

  (3) 第三种方法

给cv2.so改个名字
 

cd /opt/ros/kinetic/lib/python2.7/dist-packages/
sudo mv cv2.so cv2_ros.so

没有尝试过

给Python3配置opencv

按网上搜索到的文章来讲,使用pip3 install opencv-python即可以给python3配置上opencv,但是在我这样安装了还是不行,于是尝试

cp opencv_dir/build/lib/cv2.so ENV/lib/python3.5/site-packages/
cp opencv_dir/modules/python/src2/cv.py ENV/lib/python3.5/site-packages/

注意 :opencv-python 可以通过 sudo pip3 uninstall opencv-python 卸载

报错:'ImportError: dynamic module does not define module export function (PyInit_cv2)' error in Python?

怀疑是权限问题最后发现是python3下的自己安装module 我放在了.local/lib/python3.5/site-packages中,但是在python中的sys路径中并看不到

python3
Python 3.5.2 (default, Nov 12 2018, 13:43:14) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', '/usr/local/lib/python3.5/dist-packages', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-x86_64-linux-gnu', '/usr/lib/python3.5/lib-dynload', '/usr/lib/python3/dist-packages']
>>> 

根据这个方法 https://blog.csdn.net/sinat_27564919/article/details/55189611 将当前用户的site-packgaes 路径添加到sys中

在/usr/local/lib/python3.5/dist-packages目录下新建一个mymodule.pth的文件,将需要的路径加进如/home/panda/.local/lib/python3.5/site-packages

重新打开python 就可以看到路径添加成功了,如下图:

>>> import sys
>>> sys.path
['', '/home/panda/.local/lib/python3.5/site-packages', '/usr/local/lib/python3.5/dist-packages', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-x86_64-linux-gnu', '/usr/lib/python3.5/lib-dynload', '/usr/lib/python3/dist-packages']
>>> 

pip install & sudo pip install & pip install –user的区别

$ pip install
# 安装目录  /home/panda/.local/lib/python3.5/site-packages

$ sudo pip install     
# 在python安装中全局安装包,即对所有用户安装。
# 安装目录 /usr/local/lib/python3.5/dist-packages

$ pip install --user   #安装到本地用户目录,即~/.local/lib/python - 只是你。

dist-packages 和 site-packages 的区别


这允许你让两个安装隔离开来。

dist-packages:系统自带的python

site-packages:自己安装的python

sudo apt-get install 安装的package存放在 /usr/lib/python3.5/dist-packages目录中

pip 或者 easy_install安装的package存放在/usr/local/lib/python3.5/dist-packages目录


Ubuntu下设置环境变量有三种方法


一种用于当前终端,一种用于当前用户,一种用于所有用户:

用于当前终端:
在当前终端中输入:export PATH=$PATH:<你的要加入的路径>

不过上面的方法只适用于当前终端,一旦当前终端关闭或在另一个终端中,则无效。

export NDK_ROOT=/home/jiang/soft/Android-ndk-r8e#只能在当前终端使用。

用于当前用户:
在用户主目录下有一个 .bashrc 隐藏文件,可以在此文件中加入 PATH 的设置如下:$ gedit ~/.bashrc

加入:export PATH=<你的要加入的路径>:$PATH

如果要加入多个路径,只要:export PATH=<你要加入的路径1>:<你要加入的路径2>: ...... :$PATH

当中每个路径要以冒号分隔。

这样每次登录都会生效

添加PYTHONPATH的方法也是这样,在.bashrc中添加

export PYTHONPATH=/home/zhao/setup/caffe-master/python:/home/zhao/setup/mypy:$PYTHONPATH

保存后在终端输入 $ source ~/.bashrc使环境变量立即生效

用于所有用户:
$ sudo gedit /etc/profile

加入:export PATH=<你要加入的路径>:$PATH就可以了。

终端输入:echo $PATH可以查看环境变量

注意,修改环境变量后,除了第一种方法立即生效外,第二第三种方法要立即生效,可以source ~/.bashrc或者注销再次登录后就可以了!

 

[参考链接]

https://stackoverflow.com/questions/43019951/after-install-ros-kinetic-cannot-import-opencv 

https://blog.csdn.net/Changer_sun/article/details/81079756 

https://blog.csdn.net/qq_34544129/article/details/81946494 

 

 


原文:https://blog.csdn.net/Changer_sun/article/details/81079756