RaspberryPiでOpenCVを使ってみる【つまづき編】
やっと、OpenCVに手をだす感じになってきたのですが、即挫折させられるという運の無さ。 急いでいる人は以下の手順でOKです。
$ sudo apt-get install libopencv-dev $ sudo apt-get install python-opencv $ sudo apt-get install libgl1-mesa-dri $ x11vnc -storepasswd $ sudo mkdir /home/pi/.config/autostart/ $ sudo vim /home/pi/.config/autostart/x11vnc.desktop (設定ファイルの中身は下を参照) $ sudo vi /boot/config.txt(設定ファイルの中身は下を参照) $ sudo raspi-config(設定後再起動)
インストール作業
以前のエントリでも、opnecvの開発パッケージ、pythonのopencvモジュールの2つはインストールしていますので、あえてやらなくてもいいのかなとは思いますがバージョンアップもあるかなということで行いました。
$ sudo apt-get install libopencv-dev $ sudo apt-get install python-opencv
一ヶ月ほど前に入れたにも関わらず、バージョンアップが行われていたので時間がかかりました。
インストールを行ったOpenCVのバージョンの確認方法
インストールするとバージョンがあとからわからなくなることがあるのですが以下のファイルにバージョンが記載されています。
$ less /usr/include/opencv2/core/version.hpp
(略) /* definition of the current version of OpenCV Usefull to test in user programs */ #ifndef __OPENCV_VERSION_HPP__ #define __OPENCV_VERSION_HPP__ #define CV_VERSION_EPOCH 2 #define CV_VERSION_MAJOR 4 #define CV_VERSION_EPOCH 2 #define CV_VERSION_MAJOR 4 #define CV_VERSION_MINOR 9 #define CV_VERSION_REVISION 1 (略) /* old style version constants*/ #define CV_MAJOR_VERSION CV_VERSION_EPOCH #define CV_MINOR_VERSION CV_VERSION_MAJOR #define CV_SUBMINOR_VERSION CV_VERSION_MINOR #endif
この時点(2017/02/25)でのインストールではversionは2.4.9になっていたようです。
インストールでは難なく完了するので後はサンプルを動かすだけです。以前のエントリーでも画面表示は行っていませんでしたがUSBカメラからのキャプチャは行っていましたので、どちらかというとGUIっぽい表示にすることがメインのチェックとなります。
OpenCVのサイトに行けばサンプルも結構あるのでそれを編集しています。
カメラ画像をX上で表示する使用するサンプルcamera.py
#!/usr/bin/env python # -*- coding: utf-8 -*- import cv2.cv as cv import time cv.NamedWindow("camera", 1) capture = cv.CaptureFromCAM(0) # 画像サイズの指定 cv.SetCaptureProperty(capture,cv.CV_CAP_PROP_FRAME_WIDTH,320) cv.SetCaptureProperty(capture,cv.CV_CAP_PROP_FRAME_HEIGHT,240) while True: img = cv.QueryFrame(capture) cv.ShowImage("camera", img) if cv.WaitKey(10) > 0: break cv.DestroyAllWindows()
「カチャカチャカチャ・・・ッターンッ!!」これで出来上がったぜいぇーいとなるはずだったんです。
実行時エラーがでました。
$ python camera.py Xlib: extension "RANDR" missing on display ":11.0". (camera:31765): GdkGLExt-WARNING **: Window system doesn't support OpenGL.
お前の環境だとOpenGLに対応してね~から実行は無理というものでした。オゥフ。 これまでは画像のキャプチャのみを行っていたので表示系まではやっていなかったので気がついてイなかったみたいです。というかXを使っていなかったというのが正しいw。
今回はコンソール(Teraterm)の代わりにWindowsにデフォルトでインストールされている【リモートデスクトップ接続】を使っていました。これが原因なんだろうなあと思って、気が重くなりました。個人的には経験からLinux系の設定のツラミはほぼほとんどがX関係っていうことが多くキツイ目にあっていたので。
といっても、GUIの無い画像処理はありえないと思うので解決を模索します。
早速エラーメッセージ関係でググってみると以下の記事にあたりました。
Raspberry Pi • View topic - Enable OpenGL on Raspbian Jessie for OpenCV
内容としては「OpenGL系の対応ライブラリが入っていないのでインストールせよ」というものでした。 では早速インストールしてみます。
$ sudo apt-get install libgl1-mesa-dri
動いてくれ頼む!
$ python camera.py Xlib: extension "RANDR" missing on display ":11.0". (camera:31765): GdkGLExt-WARNING **: Window system doesn't support OpenGL.
変わっていねえ…(一部の数値とか変わるみたいですが、キャプチャ忘れました)
作戦変更へ
どうも以前入れたVNCサーバであるTightVNCserver
がX接続すると別のディスプレイ接続環境を生成して、接続を行うという特徴があるというものだったので、純粋にハード的なXではなくソフトウエア上で動いている(表現がおかしいが)Xということだったようです。
X環境は基本設定をしないと共有されるはずですが、それがTightVNCserver
にはなかったので若干不思議ではあったのですが、なんとなく理解できました。
そこでRaspberryPiのVNCサーバを
tightvncserver
から x11vnc
に変更することにします。
一応、ぐぐってみるとと実績があるようでした。
機能がバッティングしていることも考えてアンインストールしてからインストールを行っています。
$ sudo apt-get remove tightvncserver $ sudo apt-get install x11vnc
インストールは全くトラブルなく終了しました。
x11vncの設定
以下のサイトが詳しく乗っていたので参考にしました。
流れとしては
- vnc接続用のパスワード設定
- vncserverの起動
- vncviewerからの接続
となります。
それが完了したら
*自動起動を設定
を行います。
vnc接続用のパスワード設定
vncではユーザという考え方以外にもvnc用のパスワードが存在しています。そのパスワードを作成することになります。
$ x11vnc -storepasswd Enter VNC password: Verify password: Write password to /home/pi/.vnc/passwd? [y]/n y Password written to: /home/pi/.vnc/passwd
このコマンドで/home/pi/.vnc/passwd
にパスワード情報が生成されます。このパスがパスワードファイルのデフォルト場所のようです。
vncserverの起動
後はVNCサーバを起動しますがテストであれば
$ x11vnc -usepw
の実行でいいかなと思います。オプションの-usepw
は最初に設定したパスワードを使用するという宣言になります。
起動が正常にできて、このままずーっとVNCサーバを起動状態にする場合には以下の様に実行します。
$ x11vnc -usepw -forever
今回こそはとおもったんですが、失敗しました。
エラーメッセージの内容としては「VNCからXのディスプレイ:0に接続できないです」(意訳)というものでした。
ここからが苦痛でした。
エラーの内容からするとXがどうも立ち上がっていない様子。 しかし、HDMIを接続するとXは立ち上がりログインもできる。
そこで実験としてraspi-config
コマンドでCLI環境とし、HDMIを接続しない状態でターミナルを2つ立ち上げて、一つでstartx
を起動すると無事に起動しました。(WindowManegerはない状態ではあります。)そのあとにVNCServerを起動するとエラーは発生せず5900ポートで接続してほしい旨のメッセージがでました。
ここで仮説を立ててみました。
HDMIモニターを繋いでいるときにはXが起動している、RaspberryPiはHDMIを繋いでいないとコンポジット側に接続を替えるという仕様だったようなきがするので、強制的にHDMI出力をするモードに
させてしまえばXは勝手に起動してくれる?と思い、/boot/config.txt
を編集することを試してみました。
$ sudo vim /boot/config.txt
ファイル中ほどにある以下の部分のhdmi_force_hotplug=1のコメント化を解除します。
/boot/config.txt
の変更前
(略) # uncomment if hdmi display is not detected and composite is being output # hdmi_force_hotplug=1 (略)
/boot/config.txt
の変更後
(略) # uncomment if hdmi display is not detected and composite is being output hdmi_force_hotplug=1 (略)
ようやくこれでXは自動で起動してくれる様になりました。(これでほぼ1日潰れました) 後は前述のコマンドでVNCServerを起動します。
$ x11vnc -usepw 26/02/2017 13:29:15 -usepw: found /home/pi/.vnc/passwd 26/02/2017 13:29:15 x11vnc version: 0.9.13 lastmod: 2011-08-10 pid: 5984 26/02/2017 13:29:15 XOpenDisplay("") failed. 26/02/2017 13:29:15 Trying again with XAUTHLOCALHOSTNAME=localhost ... 26/02/2017 13:29:15 (略) The VNC desktop is: raspberrypi:0 PORT=5900 (略)
そしてリモートデスクトップ接続からRaspberryPiに接続、xrdp経由でVNCに接続となります。 注意点としては
を設定することになります。
ログイン画面のダイアログは以下の様になります。
ここまできたら後は、目的のサンプルプログラムを実行してみます。
うまく実行でき、やっと第一歩が踏み出せました。
後は自動起動の設定となります。
自動起動設定
まず、/home/pi/.config/autostart/
というディレクトリを作成し、そのフォルダの中にx11vnc.desktop
というファイルを作成します。
$ sudo mkdir /home/pi/.config/autostart/ $ sudo vim /home/pi/.config/autostart/x11vnc.desktop
x11vnc.desktop
[Desktop Entry] Encoding=UTF-8 Type=Application Name=X11VNC Comment= Exec=x11vnc -forever -display :0 -rfbauth /home/pi/.vnc/passwd StartupNotify=false Terminal=false Hidden=false
続いてはraspi-config
の設定をします。前述の設定ではログインしないと自動設定が行われないので自動でログインする設定にします。セキュリティとしては微妙ですが今回は目を瞑ります。
raspi-config
を起動して【3. Boot Options】を選択
画面が切り替わったら【B1. Desktop / CLI】を選択
画面が切り替わったら【B4. Desktop Autologin Desktop GUI. automatically logged in as ‘pi’ user】を選択
設定が終わったら再起動すると、リモートデスクトップから即ログインができるようになっています。
おまけ
リモートデスクトップ接続の画面が狭くなりますが、先程編集した/boot/config.txt
に解像度のパラメータもありますので、これを変更することで広くすることができます。
sudo vi /boot/config.txt
/boot/config.txt
の変更前
(略) # framebuffer_width=1280 # framebuffer_height=720 (略)
/boot/config.txt
の変更後
(略) framebuffer_width=1280 framebuffer_height=720 (略)
これで1280*720の解像度で起動が行われます。
おわりに
思った以上につまずいてしまって泣けましたが、これでもう障壁はないかなと思う(と思いたい)ので、引き続きOpenCVもやっていきたいと思います。