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

本文详细介绍了在Ubuntu16.04系统中,安装ROS Kinetic后导致Python3无法导入cv2的问题及解决方案。通过修改.bashrc文件、调整Python文件中的sys.path或重命名cv2.so,实现ROS与Python3 OpenCV的共存。

问题描述:

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.youkuaiyun.com/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.youkuaiyun.com/Changer_sun/article/details/81079756 

https://blog.youkuaiyun.com/qq_34544129/article/details/81946494 

https://blog.youkuaiyun.com/Changer_sun/article/details/81079756 

(hrl) yangs@yangs:~/hrl-nav$ python -m examples.test --scenario atc --low_level_agent_params /home/yangs/hrl-nav/tmp/hrl_nav_logs/NavGymRewardRandomize-v0/hrl/2025_05_18_19_31_32/seed_0/low_level/itr_120.pkl --high_level_agent_params /home/yangs/hrl-nav/tmp/hrl_nav_logs/NavGymHierarchical-v0/hrl/2025_05_19_18_04_58/seed_0/high_level/itr_80.pkl --spec atc rlkit/envs/wrappers/__init__.py: can not import ImageMujocoEnv. Mujoco not installed Traceback (most recent call last): File "/home/yangs/anaconda3/envs/hrl/lib/python3.6/runpy.py", line 193, in _run_module_as_main "__main__", mod_spec) File "/home/yangs/anaconda3/envs/hrl/lib/python3.6/runpy.py", line 85, in _run_code exec(code, run_globals) File "/home/yangs/hrl-nav/examples/test.py", line 12, in <module> from nav_gym_env.ros_env import RosEnv File "/home/yangs/catkin_ws/src/nav-gym/nav_gym/src/nav_gym_env/ros_env.py", line 13, in <module> from tf.transformations import quaternion_from_euler File "/opt/ros/melodic/lib/python2.7/dist-packages/tf/__init__.py", line 30, in <module> from tf2_ros import TransformException as Exception, ConnectivityException, LookupException, ExtrapolationException File "/opt/ros/melodic/lib/python2.7/dist-packages/tf2_ros/__init__.py", line 38, in <module> from tf2_py import * File "/opt/ros/melodic/lib/python2.7/dist-packages/tf2_py/__init__.py", line 38, in <module> from ._tf2 import * ImportError: dynamic module does not define module export function (PyInit__tf2)什么错误原因
最新发布
07-08
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ppipp1109

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值