2015年3月15日日曜日

raspberry pi 2(とカメラモジュール)を使った動画認識手順のメモ

1.カメラモジュールが使えるようにする(ストリーミング可能にする)
 →前回記事と同様(pi 2でもB+でも同様)

2.opencv(最新版)を導入
参考記事:
とある大学院生のプログラミング 様
http://blog.livedoor.jp/tmako123-programming/archives/41353891.html
 途中のccmakeの部分でgコマンドが効かなかった。ccmakeの後cmake → make とすることで解決した。環境の相違か?インストールには約2~3時間くらいかかった気がする。

3.opencv(python)でストリーミングから画像を取得する。
半日詰まったが以下を参考にして解決。これ以上にスマートな方法は発見できず。
stack over flow
http://stackoverflow.com/questions/21702477/how-to-parse-mjpeg-http-stream-from-ip-camera

(参考ソース:上記URLより引用)
stream=urllib.urlopen('http://localhost:8080/frame.mjpg')
bytes=''
while True:
    bytes+=stream.read(1024)
    a = bytes.find('\xff\xd8')
    b = bytes.find('\xff\xd9')
    if a!=-1 and b!=-1:
        jpg = bytes[a:b+2]
        bytes= bytes[b+2:]
        i = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8),cv2.CV_LOAD_IMAGE_COLOR)
        cv2.imshow('i',i)
        if cv2.waitKey(1) ==27:
            exit(0)   
~ここまで引用
途中に嫌な感じの部分(byteから特定文字列を検索している)があるが、現状mjpegストリーミングを正しく取得するにはこれしかない模様。あと筆者環境ではcv2.waiKey(1) ==27 が効かなかった。
waikeyの部分をa!=-1 ~のifブロックの外に出し、==27 (escキーのアスキーコード)でなく >-1とすることで中断できるようになった(筆者環境(raspberry pi 2だが)ではesc=27でなかった(100048とかそんな値)。面倒がってキーボードレイアウトをデフォルトにしている(UK)のが原因かもしれない。

4.その他(GUIウィンドウのきれいな閉じ方と特徴量抽出処理の基本)
手順3.のソースでは開いたウィンドウ「i」が正しく閉じない(pythonのexitで強制的に閉じているが)、以下の参考URLの方法でちゃんと閉じられるように改良
参考URL
stack over flow
http://stackoverflow.com/questions/6116564/destroywindow-does-not-close-window-on-mac-using-python-and-opencv

参考コード:上記より一部引用
cv2.namedWindow(WINDOW_NAME, cv.CV_WINDOW_AUTOSIZE)

cv2.startWindowThread()
 
~以下処理ループ~
 
映像処理ループの前にカラのウィンドウを生成しておき、おまじない(starWindowThread)を
行っておく必要がある(多分違うが感覚的にはマルチスレッドのsetDaemonみたいなもの)。
この後 cv2.destroyAllWindows()  や、cv2.DestroyWindow("ウィンドウ名")でウィンドウ
を閉じる。
 
・画像の特徴量抽出、記述、マッチングについては以下のHPにわかりやすくまとめてあった。
参考URL :whoopsidaisies's diary 様
 http://whoopsidaisies.hatenablog.com/entry/2013/12/07/135810
 
ちょっと前まで(FREAKが出たころ)pythonで特徴量抽出などはできなったが最近はできる模様。上記HPはc++で
解説されているが、同様のことがたいていpythonでも可能(公式ドキュメント参照)。
とりあえず抽出:FAST、記述:FREAK あたりでやってみたがストリーミングサイズ320x240で
5fps設定として処理したところ、ちょっとカクつくが処理の結果をリアルタイム(と感じなくも無い速度)で
確認できた。マッチングはまだやっていないため不明。
CPU使用率には余裕があった(30%程度使用)が、普通に使う分(マルチコアの有効活用などを意識しない運用)
にはこのくらいの処理速度が限度かという感じ。

2015年2月9日月曜日

raspberry pi でストリーミングした動画をwindowsで見る(~30fps)

1日つぶしたのでメモ。
今日調べた限りではここで紹介されているライブラリを使わないとraspberrypiカメラモジュールのストリーミングでfpsが出ない(他の手法は写真を連続で撮って配信しているものが多いため遅く、不安定)

主要参考記事
スイッチサイエンスマガジン様 : Cloud Piをつかってみました。(カメラモジュール)
http://mag.switch-science.com/2015/01/22/cloudpi_5/

Pieces for electronic kits 様 : Rasberry Piで動画のストリーミング再生をする
http://neko-kousaku.hatenadiary.jp/entry/2014/05/26/183522

参考記事内の主要ライブラリ(github)

https://github.com/jacksonliam/mjpg-streamer

参考記事中(両方)のgitクローン部分の「jacksoliam」がタイプミスしており、ここを「jacksonliam」とするとDLできた。わざとか?それともjacksonさんがタイプミスしていたのを修正したのか・・・
git clone https://github.com/jacksonliam/mjpg-streamer.git

あとは記事通りにインストール

記事通りにmjpeg-streamer を走らせ、同じLAN内のwindowsのブラウザでスムーズな動画ストリーミングできていることを確認(320x240だが) 

注意点として高FPSにすると電力を食うのかstreamer の挙動が不安定になり停止する場合がある。今回スマホ用モバイルバッテリー(2.1A 出力)を使用していたがコレが原因なのかは未確認

 

2014年4月30日水曜日

GWの工作2014 その4 ~3Dプリンタでステアリングを作ったときのメモ~

GWの前半を使ってラジコンのステアリング部分を作ったときのメモ

3Dプリンタを使った工作についての参考資料があまり無かったのでもしかしたら役に立つ人もいるかもしれない。

外観
















STLはこちら↓(Thingiverse)
https://www.thingiverse.com/thing:315540

四節リンクだの何だのを検討しまくったり試作と挫折を繰り返しながら結局とても原始的な形に落ち着いた次第。ステアリングもそうだが特にサーボをユニバーサルプレートに固定できるようになったのは進歩な気がする(サーボの回転軸もユニバーサルプレートの穴中心に合わせてある。いろいろ便利)。

その1の材料にも書いてあるが、機構部分だけで
 ・タミヤ TAMIYA 72007 4速パワーギヤボックスHE [テクニクラフトシリーズ]
 ・タミヤ TAMIYA 楽しい工作シリーズ シャフトネジセット(直径3、直径4mm) [特殊ネジ]
 ・タミヤ TAMIYA 楽しい工作シリーズ ユニバーサルアームセット
あたりが必要

筆者環境

・3Dプリンタ : makergear M2 (割りとでかいものも作れる3Dプリンタ)
1.75mmPLAフィラメント(最初からついてきたやつ)
・CAD : Cubify Design  (25000円で買えるCAD)
・Gコード生成ソフト : slic3r
・その他使った工具 : ピンバイス(φ2mmくらいのドリル付き、穴のバリ取りやわずかに穴を広げるのに使える) 例:ANEX ピンバイス収納式 ドリル付 (amazon)

3Dプリンタの精度とか設計とかについてのメモ
・前提:筆者使用のプリンタは個人用のやつでは精度やや良い方のもの(だと思う)、ちなみに積層は0.3mm/層とやや厚めにしてある。

・xy平面の穴 : サーボモータのリンク(写真左側)の長円の幅が設計値φ3.6mmに対して実測3.3~3.35mm
水平面(xy平面)の穴は外側(樹脂がある部分から無い部分の方向)に0.1~0.2mm「にじむ」と思って作った方がよさそう

・Z方向の穴(横穴) : 設計φ3.6mmに対して3.3mm(積層の関係で測定位置ごとにばらつく)、構造上やむをえないが割とガタガタ。0.1~2mm小さめに設計してピンバイスややすりで広げるか、ベアリング的なものを別に作ったほうがいい

・xy方向の凸(横方向への出っ張り) :  設計φ2.8mmに対して3~3.15mm、やはり積層の関係でばらつくし触った感じガタガタだが意外に精度は悪くない。PLAの凸を上手く削るのは面倒なので若干小さめに設計して穴凹の側で嵌め合いを調整するのが吉か。

・ 積層高さ : 当然のことながら設定した積層値の倍数でしか積層されない。高さ1mmのものを0.3mm/層で作ると0.9mmか1.2mmになると思われる(未確認)

・直径で0.3mm程度の余裕があるとスムーズに動く(写真左のサーボリンク部分)、この辺は機械設計とかの教科書なりを見たほうがいい気がする(ちなみに筆者は素人)。

更新するかもしれないが、とりあえず以上

2014年4月29日火曜日

GWの工作2014 その3 ~操作インターフェースのwebアプリ化~ 

androidのバージョンがどうたらみたいな問題に悩まされたり、
PC上でちょっとした動作テストを行うために専用コードを書いたり(PCでのテスト用にGUIのインタフェースを作ろうとも考えた)、
もしかしたらiphoneでも使いたくなるかもしれないとか考えたときの解としてhtml(とjavascript)を選択。これは今回のラジコン製作の中でも最も成果が大きかった。ブラウザがあれば大体何でも使えるインターフェースが作れるのは多分後で効いてくる。はず

~今回のお話~
pythonのwebフレームワークを使ってPCをサーバー化、websocketを使ってリアルタイム性の高い通信を行ったときのメモ

環境
・python2.7 (eclipse4.3)
・c,c++のコンパイラはmingw32
・webフレームワークとしてgevent、geventwebsocket.handlerを使用
・htmlとjavascriptはBracketsとかいうフリーソフトを使用。ライブプレビュー機能が便利。

参考資料:
geventの導入関連(筆者環境では非常に重要だった。visualstudioを普段から使っている人は素通りできるかも)
・ http://stackoverflow.com/questions/2817869/error-unable-to-find-vcvarsall-bat
(概要、上記参考URLより引用) 
C:\Python27\Lib\distutils\distutils.cfg(←ファイルが無かったら新規作成)の中身を↓

[build]
compiler=mingw32

とする(内容を追記、変更する)。そのあとプロンプトを立ち上げてgeventをインストール(↓の問題が無ければ)

・http://stackoverflow.com/questions/13592192/compiling-pygraphviz-unrecognized-command-line-option-mno-cygwin
 (概要、上記参考URLより引用)
C:\Python27\Lib\distutils\cygwinccompiler.py  というファイル内の

    self.set_executables(compiler='gcc -mno-cygwin -O -Wall',
                         compiler_so='gcc -mno-cygwin -mdll -O -Wall',
                         compiler_cxx='g++ -mno-cygwin -O -Wall',
                         linker_exe='gcc -mno-cygwin',
                         linker_so='%s -mno-cygwin %s %s'
                                    % (self.linker_dll, shared_option,
                                       entry_point))
 を
 
    self.set_executables(compiler='gcc "" -O -Wall',
                         compiler_so='gcc "" -mdll -O -Wall',
                         compiler_cxx='g++ "" -O -Wall',
                         linker_exe='gcc ""',
                         linker_so='%s "" %s %s'
                                    % (self.linker_dll, shared_option,
                                       entry_point))
 
に変更する(-mno-~というオプションを消す)
これでgeventに限らずコンパイルが必要なpythonのツールが
スムーズにインストールできるようになるはず。
 
Websocketの参考資料: 
geventを使ったwebsocketの実施例
 へきょのーと 様 記事URL http://d.hatena.ne.jp/hekyou/20120712/p1
 
上の記事を参考にしてwebsockサーバーを立て、↓のサイトで動作を確認
Echo Test  http://www.websocket.org/echo.html

htmlの参考資料:
stackoverflow http://stackoverflow.com/questions/5165579/onchange-event-for-html5-range
htmlのスライダーの値をリアルタイム変化させる為の質問。
Scott氏の回答が非常にスマート 
 
参考資料などを頼りになんとかインターフェースを構築 
メモ :
・javascriptのファイルとhtmlのファイルは別にすること
(htmlに直接スクリプトを書き込まないこと) これをやらないとIDEのエラーチェックがちゃんと機能しない

・python側、html側ともにPC(サーバー)のアドレスを127.0.0.1にしないこと。
別の機器からアクセスするとき面倒なことになるので192.168~のようにIPアドレスを記入すること

・IPカメラの映像を写すには以下のようにする。大きさはお好みで
(AI-ball(インフラストラクチャモード)の場合) 
<img src="http://(カメラのIPアドレス)/?action=stream.mjpeg" width="320" height="240"> 
(「IPwebcam」を使ったスマホの場合)
 <img src="(スマホのIPとポート)/videofeed" width="320" height="240">
 
 それぞれ上のタグを入れるだけで(大抵の)ブラウザ上に一発で動画が出る。
アンドロイドアプリで動画を出そうと苦しんでいたのは何だったのか。googleの人(?)を
問い詰めたくなるレベル。あとhtmlの仕様を策定している人たちは神
 
 肝心のインターフェースのほうは一応動かすのに必要な要素はあるが(その1の動画参照)
まだぜんぜんなのでまた今度

GWの工作2014 その2 ~VPN(SoftEther VPN)導入時に詰まった箇所のメモ~

~VPNの導入~ とか大げさなタイトルだが単純に自分が詰まったところのメモ

レジストリを変更する部分があるので自己責任で

設定時筆者環境
・win7 64bit
・NTTのフレッツ光 マンションタイプ 、プロバイダはyahooBB
・壁の電話線→NTTモデム→ルータ(BUFFALO WHR-300)→有線でPCと無線でタブレットなど
・スマホはDocomoのgalaxynote2。ドコモのケータイはVPN接続に癖があるらしいが以下のやり方(L2TP/IPsecを使用)では問題なし

導入メモ
・SoftEther VPN(https://ja.softether.org/) というVPNを導入。完全無料!筑波大学は神。オープンソースらしいので多分ずっと使えるだろう。

・基本的に上記HPのマニュアル通りに設定するだけでいける。
→チュートリアル「モバイルにおけるVPN」と「SoftEther VPN Server を使った L2TP/IPsec VPN の構成」 (一番下の方)を参照

・ マニュアルに書いてあったのだが見落としていて1日消費した箇所を以下にメモ
→見落としていたのはチュートリアル「VPN Server 側での L2TP/IPsec 機能の有効化方法 」の下の方の「VPN サーバー側に NAT がある場合」という項目の

・Windows 標準搭載の L2TP VPN クライアント機能を用いる場合で、接続先の VPN Server が NAT の背後に設置されている場合は、クライアント側のレジストリを以下のリンクの解説に従って編集する必要があります。

という文章とリンク(上の文言の下にリンクが張ってある。)。要は(ちゃんと理解してないが)外部のスマホとサーバー(今回は自宅PC)の間にNATデバイス(多分ルータのこと)がある場合はレジストリをいじる必要があるということ。リンク先を読めばわかるが筆者は値を1に変更

これをやらないとスマホでいくらがんばってもVPNが張られない(スマホからのデータがルータを通過できてもPCで弾かれる)

GWの工作2014 その1 ~スマホから動かせるラジコンの概要~

ここ最近作っていたラジコン(rev4?)のまとめ
細かいことは後の記事に個別でメモ

要約 : LANの届く範囲でなら動いたり色々入出力できる何か

主な機能 : 
1、スマホで外からでもコントロールできる。 (VPNで繋いでるだけ)。操作する人は電波さえあればどこにいてもいいがラジコンはLANの範囲(家の中)から出られない。

2、操作インターフェースはhtml+javascriptを採用。PCだろうがスマホ(androidでもiphoneでも)だろうがブラウザさえあれば関係なし。

3、前回は マルチタッチとかなんだかおしゃれなインターフェースを採用していたが、操作感が微妙だったので今回はとりあえずファミコン式(8方向のボタンで操作)

4、IP カメラで前方を見ながらのコントロールが可能。

5、arduinoとpythonの連携プラットフォームを使用しているのでいろいろ拡張可能。(そのうちちゃんとしたものができればGithubとかに上げたい)

6、無駄に駆動輪を独立駆動可能。ステアリングの操作と合わせて戦車的な挙動ができる(片方の駆動輪を中心にして回転とか)。

見た目:

上から : (前回のものと比べると)洗練された外観。まだ臓物載せただけ感は払拭できない
















 横から : 前回のラジコンはキャタピラだったが、やたら脱輪するのでタイヤに変更

















操作風景(動画)

 

ちなみにスマホのほうはWIFIではなくVPNを使って携帯の電波で動かしている。つまりスマホの電波さえ入っていれば家の中の映像を見ながらラジコンを操作できる!これで鍵の閉め忘れも確認できる(カメラの配置に課題)。
スマホ側の動画が若干カクカクしているがこれは電波が弱い為。外に出てLTEのアンテナが最大だともう少しましになった。

さっきその辺の公園から家にあるラジコンを動画のような感じで動かせることを確認(おもむろに公園のベンチに座りスマホでラジコンの動作確認をしてすぐ立ち去る様は若干不審人物だった気がする)。

材料 : 
(´д`;).oO(材料のリンクをアドセンスにすれば小遣い稼ぎができるのでは・・・ゴクリ。と思ったがそんなアクセス無かった。)
 気を取り直して材料リスト(以下に無いものも写真に写っているが今回は使ってないのでカット)

ヨドバシ.comで購入 (タミヤの部品はヨドバシが便利だった201404月現在)
・タミヤ TAMIYA 楽しい工作シリーズ ユニバーサルプレート(210×160mm)
・タミヤ TAMIYA 楽しい工作シリーズ ユニバーサルプレート(2枚セット)
・タミヤ TAMIYA 楽しい工作シリーズ ナロータイヤセット(58mm径)  ×2
・タミヤ TAMIYA 72007 4速パワーギヤボックスHE [テクニクラフトシリーズ] ×2
・タミヤ TAMIYA 楽しい工作シリーズ シャフトネジセット(直径3、直径4mm) [特殊ネジ] ×2くらい
・タミヤ TAMIYA 楽しい工作シリーズ ユニバーサルアームセット
スイッチサイエンスで購入 (同等品でも可。ただしArduino Leonardo系は何となくおすすめしない )
・デュアル・モータードライバTB6612FNG(連続最大1.2A)
・リチウムイオンポリマー電池×2
・Arduino Uno R3
・XBee ZB モジュール ×2
・XBeeエクスプローラUSBドングル
・XBee 5Vインターフェースアダプタ
・SparkFun製 プロトシールド・キット
・ジャンパワイヤ ×適量

アマゾンで購入。IPカメラなら何でもいい(余ったスマホに「IPwebcam」をインストールしたもので問題ない。というより重さ以外はコレがおすすめ)
・Trek 2000  Ai-Ball (写真ではなにやら回路がくっついているが(写真1枚目左側)、これは3.3V出すための電源回路。弄り倒して付属の電源アダプタをぶっ壊していなければ不要)

秋月電子で購入
・GWSサーボ PIC+F/BB/F(フタバ) (設定値、スペックなどは過去記事参照)




2014年2月23日日曜日

xbee wifiに関する走り書き

xbee wifiをソケット通信で普通に使うのに必要そうな情報

受信と送信のソケットを同時に開くことは(多分)できない。送信(または受信)が終わったらそのたびにソケットを閉じること

・基本だがsocket.accept()の直後に(ウェイトを入れずに) socket.recv() などでデータを取り出そうとしてもエラーになる。バッファがちゃんと溜まるまで(人間にとって)ちょっとでも待つべき。

・連続してデータの送受信を繰り返したいとき、デフォルトの設定だと受信(PC←xbee)で10秒、送信で多分60秒くらい待つようになっている。「Network」のTMとTSが受信と送信のタイムアウトになっているのでこれらを限界まで小さくすると待ち時間が減らせる(とりあえず0.5秒に1回程度の送受信ができる)

・「serial Interfacing」のROもタイムアウトになっている。小さくすると通信が多分速くなる。

・送受信のソケットを再生成するのにも時間が必要なので繰り返す場合は生成前にウェイトを入れること。

とりあえず上記で(電源系の問題を除けば)普通のxbeeと同じように使えるはず。詳細は来週