この script を使用して、ソースからopenCVを最初にインストールしました。私がテストしたとき、それはうまくいった。
ROS kinetic をインストールし、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
この問題はpythonパスに/opt/ros/kinetic/lib/python2.7/dist-packages
を追加するROSが原因であるようです。これは、コマンドsource /opt/ros/kinetic/setup.bash
でROSをアクティブにしたときに実際に起こります。この行は、bashrcファイルの最後の/home/username/.bashrc
に追加されることがよくあります。
回避策は、bashrcファイルからこの行を削除することです。これにより、python3 opencvパッケージが正しく使用され、source /opt/ros/kinetic/setup.bash
を実行してROSを使用できます。ただし、これは同じ環境からROSとpython3を使用できないことを意味します。
誰かがより良い答えを思いつくことができれば幸いですが、それまではうまくいくはずです。
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')
ローカルでコンパイルされたopencvを使用して、anaconda3でpython3.5でテストしました。これはおそらくvirtualenvs
にも当てはまります。
永続的な解決策として、@ Paulの回答に記載されているように、'/opt/ros/kinetic/lib/python2.7/dist-packages'
からパス~/.bashrc
を削除します。
まったく同じ問題を抱えていました。問題は、ROSがpython 2用の独自のcv2.soファイルを作成し、すべてのインポート要求をそのファイルにルーティングすることです。それは非常に簡単な修正です:
サイトパッケージフォルダーに移動します
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
そして、それは物事を修正するはずです!
ステップ1:cv2.soがインストールされているパスを見つけます(python-cv wheelを使用してopencvをインストールする場合)
ステップ2:次のように、パスを.bashrcまたは.zshrcファイルにエクスポートします。
export PYTHONPATH="/home/userx/anaconda3/lib/python3.5/site-packages:$PYTHONPATH"
@ lxrd-aj に感謝
指摘したように、source /opt/ros/kinetic/setup.bash
の.bashrc
コマンドはPYTHONPATH
を次のように変更します。
> echo $PYTHONPATH
/opt/ros/kinetic/lib/python2.7/dist-packages
私の場合、Python 3プロジェクトにvirtualenvを使用しているので、virtualenvがアクティブになっている間に次のコマンドを実行してPYTHONPATH
変数をクリアしました。
unset PYTHONPATH
これで、Python 3 virtualenvでのcv2
のインポートが正常に機能します。 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をアクティブにするたびにこのコマンドを実行する必要がないように、次のようにvirtualenvディレクトリの/bin/activate
ファイルに追加しました。
...
# unset irrelevant variables
deactivate nondestructive
unset PYTHONPATH
VIRTUAL_ENV="/home/kaiyuzh/pyenv/py3"
export VIRTUAL_ENV
...
/opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so.
を削除しようとしましたが、今は動作しています。
実際、私もこの問題に直面しています。ソースをコメントアウトしました。
/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をインポートできなかった問題を解決するのに役立ちました。
(私の場合のように)これらの解決策がどれもうまくいかない場合でも、正しい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')
おそらく、cv2をインポートした後、正しい場所でros pythonパスを置き換えることを検討するかもしれません。
おそらくpython3 cv2ライブラリ(cv2.cpython-35m-x86_64-linux-gnu.soの奇妙な命名のために、パスが正しく設定されていても、私のpythonは正しいcv2のインポートに問題があるようです。 )/opt/ros/kinetic/lib/python2.7/dist-packagesにあるcv2.soと比較して
ここで同様の問題。他の人が示唆したように、/opt/ros/kinetic/setup.bash
はPYTHONPATH
変数にROS opencvへのパスを追加します。
複数のvirtualenv
sを使用していて、ほとんどの場合に機能するソリューションが必要な場合は、.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
sの集中ディレクトリがある場合(たとえば、virtualenvwrapper
を使用する場合)、次を使用してそれらのディレクトリを検索できます。
$(find ~/.virtualenvs/ -mindepth 1 -maxdepth 1 -type d)
すべてのvirtualenv
sが~/.virtualenvs
の下にあると仮定します。これにより、すべてのvirtualenv
sルートディレクトリのリストが表示されます。
その後、virtualenvディレクトリの配列をループ処理し、PYTHONPATH
にパス(たとえば、~/.virtualenvs/testenv/lib/python2.7/site-packages
)を追加しています。これはafter the source /opt/ros/kinetic/setup.bash
だけで行う必要があることに注意してください。
2つのenvのopencvバージョンが異なる場合でも競合が発生する可能性があるため、問題の完全な解決策ではありませんが、最初の問題については、少なくとも機能するはずです。
または、目的のvirtualenvに対して同じトリックを手動で行うこともできます。
export PYTHONPATH=~/.virtualenvs/testenv/lib/python2.7/site-packages:$PYTHONPATH
/opt/ros/kinetic/setup.bash
を実行するROSセットアップ中に、他のものの間のスクリプトはpython2とpython3のすべての配布パッケージに移動し、pythonシステムパスに追加します。 python3を使用してcv2
をインポートしようとすると、パスに含まれているPython2のcv2バインディングが最初に見つかります。
ROSプロジェクトでpython2.7をまったく使用しない場合は、python2.7 OpenCVパッケージを完全に削除することを検討してください。rosセットアップスクリプトの実行時にパスに追加されません。
$ rm /opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so
両方のPythonバージョンの使用を計画している場合の別のより穏やかなアプローチは、正しいバインディングを使用して2つの仮想環境を作成し、要件に応じていずれかをアクティブにすることです。