1. 程式人生 > >Ubuntu16.04 安裝了ROS Kinetic之後Python3不能import cv2

Ubuntu16.04 安裝了ROS Kinetic之後Python3不能import cv2

安裝了ROS Kinetic之後Python3不能import Opencv

問題描述如下:

Python 3.5.2 (default, Nov 23 2017, 16:37:01) 
[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 >>> Python 2.7.12 (default, Dec 4 2017, 14:50:18) [GCC 5.4.0 20160609] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> 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

解決方法是從bashrc檔案中刪除此行。

這樣就可以正確使用python3 opencv包,你仍然可以執行source /opt/ros/kinetic/setup.bash使用ROS。但是,這確實意味著無法在同一環境中使用ROS和python3

就是說,在用python3執行opencv3 即import cv2

的時候需要把.bashrc 或者 .zshrc中的有關ros的soure都註釋掉,才可以正常執行

給Python3配置opencv

按網上搜索到的文章來講,使用pip install opencv-python即可以給python3配置上opencv,但是在我這樣安裝了之後還是不行,於是選擇了sudo pip install opencv-python但是出現瞭如下的錯誤:

The directory '/home/sun/.cache/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
The directory '/home/sun/.cache/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Requirement already satisfied (use --upgrade to upgrade): opencv-python in /home/sun/.local/lib/python3.5/site-packages
Requirement already satisfied (use --upgrade to upgrade): numpy>=1.11.1 in /home/sun/.local/lib/python3.5/site-packages (from opencv-python)
You are using pip version 8.1.1, however version 10.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

搜尋之後發現解決方案如下:使用sudo -H pip3 install opencv-python安裝即可

# 安裝之後 進入/usr/local/lib/python3.5/dist-packages/ 會發現有一個cv2的資料夾 裡邊有.so檔案
[email protected]  /usr/local/lib/python3.5/dist-packages/cv2  ls
cv2.cpython-35m-x86_64-linux-gnu.so  data  __init__.py  LICENSE-3RD-PARTY.txt  LICENSE.txt  __pycache__

pip install & sudo pip install & pip install –user的區別

$ pip install
# 安裝目錄  /home/sun/.local/lib/python3.5/site-packages
$ sudo pip install     
# 在python安裝中全域性安裝包,即對所有使用者安裝。
# 安裝目錄 /usr/local/lib/python3.5/dist-packages
$ pip install --user   #安裝到本地使用者目錄,即~/.local/lib/python - 只是你。 

檢視python的安裝路徑

Python 2.7.12 (default, Dec  4 2017, 14:50:18) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', '/home/sun/WorkSpace/Ros_workspace/catkin_cartographer/install_isolated/lib/python2.7/dist-packages', '/home/sun/WorkSpace/Ros_workspace/catkin_slam/devel/lib/python2.7/dist-packages', '/opt/ros/kinetic/lib/python2.7/dist-packages', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/home/sun/.local/lib/python2.7/site-packages', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/python2.7/dist-packages/wx-3.0-gtk2']
>>> 
Python 3.5.2 (default, Nov 23 2017, 16:37:01) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', '/home/sun/WorkSpace/Ros_workspace/catkin_cartographer/install_isolated/lib/python2.7/dist-packages', '/home/sun/WorkSpace/Ros_workspace/catkin_slam/devel/lib/python2.7/dist-packages', '/opt/ros/kinetic/lib/python2.7/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', '/home/sun/.local/lib/python3.5/site-packages', '/usr/local/lib/python3.5/dist-packages', '/usr/lib/python3/dist-packages']
>>> 

dist-packages 和 site-packages 的區別

這允許你讓兩個安裝隔離開來。

  • dist-packages:系統自帶的python

  • site-packages:自己安裝的python

  • sudo apt-get install 安裝的package存放在 /usr/lib/python2.7/dist-packages目錄中

  • pip 或者 easy_install安裝的package存放在/usr/local/lib/python2.7/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或者登出再次登入後就可以了!