2014年12月12日金曜日

Intel Edisonで映像配信中のカメラのパン・チルトを制御してみた

はじめに



にて、Intel EdisonにてWebカメラを有効にし、mjpg-streamerで映像を配信してみました。

今回は、Intel Edisonを使ったデモとして、そのWebカメラにサーボモーターを2つ取り付け、Web経由でパン・チルト(水平方向と垂直方向)を制御してみました。

全体像は下図のようになります。カメラの他は、Intel Edison Breakout Board、レギュレータやレベルシフタを含む周辺回路、バッテリー(Eneloop Pro6本)が見えます。

コントローラーはPC、タブレット、スマートフォンなどのブラウザです。



動作状況の動画はこちらになります。




カメラ雲台の準備

カメラとサーボモータ2つを接続する方法ですが、なるべく楽をしたかったので、秋月電子通商にある


を用いました。



この組み立て方は


にあります。これを見るだけでも大変そうなのはわかりますが、実際に手元に届いてみると

  • ニッパ、ピンバイス、ヤスリによるパーツの加工が必須
  • 必要なネジが全然足りない(と思う)
  • 2つのサーボSG-90の品質が悪く、最初から正常動作しないことがある

のように、なかなか骨のあるキットです。

ちなみにサーボSG-90は秋月やamazonなどでも追加注文できますが、店によってはバージョン違いなのかサーボのケースサイズやサーボホーンの径が異なり、さらに加工が必要になったりします。なお、私の場合、SG-90を計12個入手して、正常動作したものは10個でした。

さらに、このキットに付属するWebカメラはMJPEGモードに対応していないので、「Intel EdisonでWebカメラを有効にしmjpg-streamerで映像を配信してみた 」で紹介した方法では映像配信できません。

私は手元で余っていたLogicool C210を加工して取り付けました。Logicoolのものなら大抵大丈夫だと思います(今にして思えば、もっと画質の良いものにすれば良かったかも)。


回路の接続

作成したカメラ雲台を下図のようにIntel Edisonと接続します。


いくつかコメントします。

USBカメラを使うため、電源は7V~15VをJ21に入力します。バッテリーを用いたかったので、Enelooop6本を用いることにしました。容量の大きいEneloop Proにしましたが、これはお好みで。

サーボモーターは5Vで駆動するため、レギュレータTA4805Sで5Vを作ります。これは手元にあったものをそのまま用いました。

Intel Edisonからは下記の5つの信号を引っ張りだしました。Intel Edisonを外した状態で、Breakout Boardにケーブルを直接半田づけしました。

  • J17-1:サーボ用PWM
  • J18-1:サーボ用PWM
  • J18-2:GPIO。プルアップされた入力として用いて、シャットダウンスイッチに利用します。
  • J19-2:1.8V
  • J19-3:GND
各ピンの情報はIntel Edison Breakout Board Hardware GuideのPDFファイルを参考にしてください。

サーボモータ用に出力するPWM信号は1.8Vなので、サーボモータに与えるために5Vにレベル変換します。これも手元にあった「8ビット双方向ロジックレベル変換モジュール」を用いました。

PCとの接続は、J3のシリアルコンソールにより行います。

libmraaライブラリの準備

ここからはIntel Edison上での作業になります。あらかじめ、「Intel EdisonでWebカメラを有効にしmjpg-streamerで映像を配信してみた」に基づいてWebカメラの映像配信を有効にしておいてください。エントリ作成当時はポート8080を用いていましたが、ポート9000を用いるように変更しましたので、ご注意ください。

さて、スイッチサイエンスさんのページ「Intel Edison opkgのフィードを設定する」および「libmraaを使ってC++で開発する」を参考に、GPIOにアクセスするためのlibmraaライブラリをインストールします。

# vi /etc/opkg/myfeeds.conf

このファイルに下記の内容を記述して保存します。

src intel-iotdk http://iotdk.intel.com/repos/1.1/intelgalactic
src all http://iotdk.intel.com/repos/1.1/iotdk/all
src i586 http://iotdk.intel.com/repos/1.1/iotdk/i586
src x86 http://iotdk.intel.com/repos/1.1/iotdk/x86

書けたら、下記のコマンドを実行します。

# opkg update
# opkg upgrade
# opkg install libmraa0

これでlibmraaのインストールが完了しました。

node.jsで用いるモジュールの準備

node.jsによるWeb連携で用いるconnectモジュールとsocket.ioモジュールをインストールします。

# npm install connect@2.27.4
# npm install socket.io@0.9.17

使っているスクリプトの関係上、バージョンを指定して最新のものではないファイルをインストールしました。

これらのモジュールは/home/root/node_modules以下にインストールされます。

なお、libmraaライブラリに対応するmraaモジュールは/usr/lib/node_modules/mraaとしてインストールされていますが、これを/home/root/node_modulesにリンクしておかないと、自作のnodeスクリプトを/etc/rc.localから起動するときに失敗します。そのため、下記を実行しておきます。

# ln -s /usr/lib/node_modules/mraa /home/root/node_modules/mraa

ソースのダウンロード

ソースのダウンロードのために、gitをインストールします。

# opkg update
# opkg install git

次に、ソースをダウンロードし、pantiltという名前のディレクトリに保存します。

# cd
# git clone https://github.com/neuralassembly/Edison_pantilt.git pantilt

以下、いくつか解説を加えていきます。

シャットダウンスイッチ

シャットダウンスイッチを有効にするためには、下記のコマンドを実行します。

# python /home/root/pantilt/shutdown.py &

この状態で、回路上のタクトスイッチを2~3秒程度長押しすると、poweroffコマンドが実行され、シャットダウンが始まります。

中身は下記のようなPythonプログラムになっています。GPIO15はJ18-2のことであり、プルアップ抵抗つきの入力として設定しています。GPIO番号とピン番号の対応はこちらを参照。

import mraa
import time
import subprocess

sw = mraa.Gpio(15)
sw.dir(mraa.DIR_IN)
sw.mode(mraa.MODE_PULLUP)

state = 0

while True:
    if sw.read() == 0:
        if state == 2:
            state = 0
            args = ['poweroff']
            subprocess.Popen(args)
        else:
            state += 1
    else:
        state = 0

    time.sleep(0.5)

このshutdown.pyスクリプトを起動時に有効にするには、mjpg-streamerの自動起動の際に作成した/etc/rc.localに上記のコマンドを追記してください。

サーバーの起動

サーバーを起動するには、下記のコマンドを実行してください。

# node /home/root/pantilt/pantiltserver.js &

その状態でブラウザで


  • http://(Intel EdisonのIPアドレス):8080/


にアクセスすると、操作用のアプリが開きます。使用されているポートは下記の通りです。

  • 8080:ページの閲覧
  • 8888:socket.ioによるソケット通信
  • 9000:mjpg-streamerによる映像配信

JavaScriptで記述したpantiltserver.jsの中では、下記のようにJ17-1およびJ18-1ピンに対してPWM信号を出力しています。

var mraa = require('mraa');
var p0 = new mraa.Pwm(0);  // J17-1
var p1 = new mraa.Pwm(14); // J18-1

p0.period_us(19500);
p0.enable(true);
p1.period_us(19500);
p1.enable(true);

// For upper servo
var duty0min = 0.03; // min
var duty0max = 0.11; // max
var duty0 = (duty0min + duty0max)/2;

// For lower servo
var duty1min = 0.031; // min
var duty1max = 0.115; // max
var duty1 = (duty1min + duty1max)/2;

p0.write(duty0);
p1.write(duty1);

サーボモータに50Hzの信号を与えるのですが、細かな周期やパルス幅はオシロスコープの波形を見たりサーボモーターの振る舞いを見ながら微調整しました。Duty比は0~1の実数で指定します。

このpantiltserver.jsをIntel Edison起動時に自動実行する場合は、やはり/etc/rc.localに上記コマンドを追記してください。

ブラウザ上のアプリ

ブラウザのアプリは下図のように映像の下と右にjQuery UIによるスライダを配置してサーボモーターへの指令をJavaScriptで送るようにしています。iOSのSafari/ChromeやAndroidのChrome/Firefoxなどで動作を確認しています。画面の回転にも対応しています。



このアプリは、主に下記のファイルで構成されています。

  • index.html
  • js/pantilt.js
  • js/socket.io.js:node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.jsと同じもの
  • js/jquery/:jQuery UI用ファイル
  • css/pantilt.css

js/pantilt.js内で、映像の取得と命令の送信を行っています。

展示

このデモを2014年12月21日に東海大学高輪キャンパスで開催されたAndroid Bazaar and Conference 2014 Winterで展示しました(週アスPLUSさんにも写真があります)。


Androidのイベントなので、カメラを「Androidタブレットおよびそれとペアリングされた腕時計Android Wear」から操作できるデモとしました。Android Wearでの操作の技術的詳細は、「Android Wear (LG G Watch) でカメラからの映像を見ながら三輪ロボットを操作してみた」が関連します。

沢山の方にお越しいただき、ありがとうございました。

終わりに

Intel Edisonを用いた簡単なデモということで、カメラのパンチルトを制御してみました。

mraaモジュールを用いるとJavaScriptで直接GPIOにアクセスできるので、Web連携が容易であるという印象を持ちました。ただし、ドキュメントがあまり充実していないように思われるのが残念なところです(Pythonの入力ピンのプルアップ抵抗を有効にする方法を調べるために、mraaのソースをgrepしたりしました)。そのあたりは今後に期待でしょうか。

あとは、7V以上の電源の確保と1.8VのGPIO入出力のレベルシフトがやや面倒、というところです。

他のボードとの比較で言えば、Raspberry Piで同じことをやろうとする場合、Webカメラでは性能が出ないので、Raspberry Pi用のカメラモジュールを用いる必要があります。さらに、Raspberry PiではハードウェアPWMが一つしか使えないので、全く同じことをするのは少し面倒です。

BeagleBone Blackでは全く同じことを実現できるはずですが、私はBeagleBone BlackでのGPIOプログラミングは未経験なのでノーコメントです。

以上でした。

2014年12月3日水曜日

Intel EdisonでWebカメラを有効にしmjpg-streamerで映像を配信してみた

はじめに


(2015.2.27 内容をアップデートしました)

Intel Edisonは特に使い途が思いつかなかったので手を出していなかったのですが、2014月11月末のMaker Faire Tokyo 2014にて初めて実物を見たことと、スイッチサイエンスさんのブースで「スイッチサイエンス版Eaglet (MFTバージョン)」を購入したことをきっかけに、試してみることにしました。

目指すのは、いつもやっている「Webカメラを接続してmjpg-streamerで映像を配信する」こととします。

結果を先にお見せすると下図のような感じでです。Intel Edisonで配信した映像がAndroidタブレットに表示されていることがわかります。

なお、本ページで言う「Intel Edison」は、ほとんどの場合「Intel Edison Breakout Board Kit」を指していますのでご了承ください。


Intel Edisonのアップデート

このブログを執筆した2014年12月当時は、Intel EdisonでWebカメラを使うために、OSのイメージを自分でビルドする必要がありました。しかし、2015年1月に公開されたバージョンでは、デフォルトでWebカメラを利用可能になっています。

そこで、ここではまずその方法を解説します。Intel EdisonでのOSのイメージをビルドする方法が知りたい方は、このページの末尾に記録を残しておきますのでご覧ください。

本ページでは、Intel EdisonのアップデートをUbuntuで行うことにします。
まず、Ubuntuにて

$ sudo apt-get install dfu-util

を実行してdfu-utilをインストールしておきます。

次に、こちらよりYocto complete imageをダウンロードします。2015年2月27日の時点ではedison-image-ww05-15.zipがダウンロードされました。

その後、edison-image-ww05-15.zipと同じディレクトリにいるとして、下記のコマンドで書き込みます。

$ mkdir edison-image-ww05-15
$ cd edison-image-ww05-15
$ unzip ../edison-image-ww05-15.zip
$ sudo ./flashall.sh

このコマンドによりアップデートの待機状態になるので、Intel EdisonのJ16コネクタとUbuntuマシンをUSB接続してIntel Edisonに電源を投入すると、アップデートが始まります。J3コネクタにてシリアルコンソールに接続しておくと、進行状況がわかって安心です。

なお、UbuntuマシンとIntel Edisonとを既に接続済みだった場合はIntel Edisonをリブートすると、起動時に更新が始まります。

再起動が終わったら、Intel EdisonのJ16コネクタにUSBカメラ(要変換コネクタ)、J21ピンに7V~15Vの電源を接続します。J3コネクタのシリアルコンソールでログインすると、/dev/video0ができていることがわかります。

なお、この状態でIntel Edisonを再起動すると、カメラが認識されなくなります。一度電源を切ってから再投入することで認識されるようです。

mjpg-streamerのインストールと起動

ここからは主にシリアルコンソールで接続したIntel Edison上の作業になりますが、まず、「configure_edison --setup」コマンドにより、あらかじめIntel EdisonをWifi接続しておきます。詳細はスイッチサイエンスさんのページが詳しいです。

また、あらかじめUbuntuマシンでmjpg-streamerのソースをダウンロードしておきます。このダウンロードにはSubversionが必要なのですが、Intel Edison用のSubversionのパッケージが見当たらず、ソースからインストールするのは面倒だったため、Ubuntuであらかじめダウンロードしておく、というわけです。

(Ubuntuマシンで)
$ sudo apt-get install subversion
$ svn co https://svn.code.sf.net/p/mjpg-streamer/code/mjpg-streamer mjpg-streamer

そして、できたmjpg-streamerディレクトリをWifi経由でIntel Edisonへ移動しておきます。

ここからIntel Edisonでの作業です。

まず、スイッチサイエンスさんのページ「Intel Edison opkgのフィードを設定する」を参考に、myfeeds.confというファイルを作成して編集を開始します。
# vi /etc/opkg/myfeeds.conf
このファイルに下記の内容を記述して保存します。
src intel-iotdk http://iotdk.intel.com/repos/1.1/intelgalactic
src all http://iotdk.intel.com/repos/1.1/iotdk/all
src i586 http://iotdk.intel.com/repos/1.1/iotdk/i586
src x86 http://iotdk.intel.com/repos/1.1/iotdk/x86
書けたら、下記のコマンドを実行します。
# opkg update
# opkg install libjpeg-dev libv4l-dev
# cd mjpg-streamer
# vi Makefile

ここで、Makefileの39行目でinput_testpicture.soをビルド対象に含めている部分を下記のようにコメントアウトします。

# PLUGINS += input_testpicture.so

input_testpicture.soのビルドにはImageMagickが必要なのですが、ImageMagickのIntel Edison用のパッケージがなく、またその名前の通り、input_testpicture.soはテスト時以外なくても困らないためです。

以上のもと、ビルドします。

# make

ビルドが完了したら、下記のコマンドにより、mjpg-streamerを起動します。

# export LD_LIBRARY_PATH="$(pwd)"
# ./mjpg_streamer -i "./input_uvc.so -d /dev/video0 -r 640x480 -f 15" -o "./output_http.so -p 9000 -w ./www"

あとは、ブラウザで

http://Intel EdisonのIPアドレス:9000/

にアクセスすると、映像が配信されていることがわかります(2014.12.11追記。後に追加するエントリとの整合性をとるため、ポート番号を8080から9000に変更しました)。

Androidの場合は簡単MJPEGビューアを使ってもよいです。ポート番号はソフトウェアキーボードで9000と変更してください。

mjpg-streamerの自動起動

最後に、Intel Edisonに電源を入れた際にmjpg-streamerが自動で起動するようにしておきます。

まず、mjpg-streamerディレクトリにstart_mine.shファイルを作成します。

# cd
# vi mjpg-streamer/start_mine.sh

中には例えば以下の内容を記します。

#!/bin/sh

cd /home/root/mjpg-streamer
export LD_LIBRARY_PATH="$(pwd)"
./mjpg_streamer -i "./input_uvc.so -d /dev/video0 -r 640x480 -f 15" -o "./output_http.so -p 9000 -w ./www"

次に、このスクリプトを/etc/rc.localに記述して、起動時に自動的に呼び出されるようにします。

# vi /etc/rc.local

内容は下記の通りです。

#!/bin/sh

sh /home/root/mjpg-streamer/start_mine.sh &

最後に、/etc/rc.localのパーミッションを755にしておきます。

# chmod 755 /etc/rc.local

以上が済んだ後、Intel Edisonの電源を切り、電源再投入してください(リブートでは駄目)。mjpg-streamerが自動で起動していることがわかるはずです。

終わりに

Intel EdisonでWebカメラの映像を配信してみましたが、Raspberry PiやBeagleBone Blackと比べた場合のメリットは、5GHz帯のネットワークにデフォルトで接続できることでしょうか。Raspberry PiやBeagleBone Blackで5GHz帯のネットワークにつなぐにはGW-450Dを使う方法がありますが、kernelの再構築が必要であるなど、やや面倒です。

とは言え、Intel Edisonの方でも、7V~15Vの電源が必要な点など使いにくいところはあります。

以上です。

こちらもどうぞ

このページの話の続きです。




kernelとOSイメージの作成

既に述べたように、2014年12月の時点では、EdisonのデフォルトのkernelはUSB Video Class (UVC)が有効になっていなかったので、それを有効にしたkernelと、それを含むOSイメージを作成する方法を解説しました。

現在はUVCがデフォルトで有効になっていますのでこの作業は必要ないのですが、記録としてその方法を以下に残しておきます。

この作業はUbuntuで行いました。作業の概略はIntel Edison BSP User Guideにまとめられています。

まず、Ubuntuに必要なパッケージをインストールします。

$ sudo apt-get update
$ sudo apt-get install build-essential git diffstat gawk chrpath texinfo libtool gcc-multilib

次に、こちらよりLinux source filesをダウンロードします。2015年2月27日の時点ではedison-src-ww05-15.tgzでした。このファイルを

$ tar zxf edison-src-ww05-15.tgz

により解凍します。edison-srcというディレクトリができますので、以下の順でまずはデフォルトのイメージを作成してみます。なお、この際環境変数PATHにカレントディレクトリ「.」が含まれているとエラーが出ますので、あらかじめPATHから「.」を削除しておきます。

$ cd edison-src
$ ./device-software/setup.sh
$ source poky/oe-init-build-env
  (ここで、自動的にedison-src/buildにcdされる)
$ bitbake edison-image

なお、最後のコマンドを実行すると、途中で様々なファイルのダウンロードが行われますが、環境やタイミングによりダウンロードエラーが起こることがありますので、エラー出ずにビルドが終了するまで繰り返します。

私の場合、成功時に下記のようなメッセージが現れてビルドが完了しました。

NOTE: Tasks Summary: Attempted 2802 tasks of which 29 didn't need to be rerun and all succeeded.

Summary: There were 79 WARNING messages shown.

ビルドが完了した後、以下のコマンドにより、書き込み用のファイル群をまとめます。

$ cd ../..
$ ./edison-src/device-software/utils/flash/postBuild.sh

以上により、書き込み用のファイルがディレクトリedison-src/build/toFlashにまとめられます。このイメージを上で行ったようにflashall.shを用いて書き込めます。

なお、kernelの設定を変更したい場合は下記のようにして再ビルドしてください。
kernelの設定ファイルはedison-src/device-software/meta-edison/recipes-kernel/linux/files/defconfigですので、手作業で変更する場合はこちらを編集します。

menuconfigにより設定を行う場合は以下のようにします。まず、
edison-src/build ディレクトリにて

$ bitbake virtual/kernel -c menuconfig

を実行します (Xが必要)。

Webカメラを有効にする場合は下記の操作を行ったのですが、既にこれはデフォルトで有効になっています。
Device Drivers→
MultiMedia Support→
Media USB Adapters でスペース→Enter
USB Video Class (UVC) で M
→Save
→Exit (複数回)
と辿ることで設定ファイルが

edison-src/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17+gitAUTOINC+6ad20f049a_c03195ed6e-r0/linux-edison-standard-build/.config

として書き込まれます。これをkernelの設定ファイルの格納場所にコピーします。
edison-src/buildディレクトリにいるとして、

$ cp ../device-software/meta-edison/recipes-kernel/linux/files/defconfig ../device-software/meta-edison/recipes-kernel/linux/files/defconfig.orig
$ cp tmp/work/edison-poky-linux/linux-yocto/3.10.17+gitAUTOINC+6ad20f049a_c03195ed6e-r0/linux-edison-standard-build/.config ../device-software/meta-edison/recipes-kernel/linux/files/defconfig

さて、以上が済んだら、edison-src/build ディレクトリにて下記コマンドによりイメージの作成を行います。

$ bitbake virtual/kernel -c configure -f -v
$ bitbake edison-image
$ cd ../..
$ ./edison-src/device-software/utils/flash/postBuild.sh

以上で、edison-src/build/toFlashに書き込み用のファイルができました。


2014年11月2日日曜日

Raspberry PiとArduinoで16x32 RGB LEDパネルにカメラモジュールの映像を表示してみた

はじめに

5月頃に秋月で「RGBフルカラードットマトリクスLEDパネル 16x32ドット」を購入し、長いこと放置していたのですが、少し時間ができたので試してみることにしました。

最近ずっと仕事で使っていたRaspberry Piで試すことにします。ただし、Raspberry Piに直接接続するわけではなく、

RaspberryPi―(シリアル通信)→Arduino→RGB LEDパネル

という構成にしました。そうすることで、Adafruitで公開されているArduino用のライブラリを流用することができます。

なお、この構成で始めた後に、やはりAdafruitでRaspberry Pi用のチュートリアルが出てることを知りました。そちらのチュートリアルでは画像ファイルをスクロールする例を取り扱っていますが、本ページでは、それとは異なる構成でRaspberry Piのカメラモジュールの映像をRGB LEDパネルに表示するところまでを試してみます(下図)。


準備

まず、AdafruitのArduino用のチュートリアルを元に、Arduinoで動作することを確かめてください。ArduinoのIDEでFile→Examples→RGBmatrixPanelとたどった時に「16x32」が含まれているサンプルは動作します。

用いるArduinoはチュートリアルにあるようにArduino Unoで良いですが、私は「Arduino Pro Mini 328 5V 16MHz」+「FT232RL搭載小型USB-シリアルアダプタ 5V」の組み合わせを用いました。ソースを少し変更するだけでArduino Megaでもいけるようですが、こちらでは試していません。

C++ & OpenCVの場合

それでは、Raspberry Piでの準備に入っていきます。Raspberry Piのカメラモジュールの映像を取得し、それをRGB LEDパネルに表示することを目指しますが、そのためにC++とOpenCVの組み合わせを用いることにします。

最初はPythonと画像処理ライブラリのPillowの組み合わせで試していたのですが、思った速度が出なかったので、C++とOpenCVの組み合わせに切り替えました。Python+Pillow版についてはページ末尾にメモを残しますので、興味のある方はどうぞ。

さて、Raspberry Pi、Arduino、RGB LEDパネルを下記のように接続しておきます。この場合、Arduinoの電源はRaspberry PiのUSBから供給されます。



さらに、Raspberry Piではカメラモジュールを使えるようにしておきましょう。「sudo raspi-config」で設定を起動し、「5. Enable Camera」→「Enable」とたどれば良いのでした。

次に、Raspberry PiでOpenCV、および後に必要なcmakeをインストールします。

sudo apt-get update
sudo apt-get install libopencv-dev cmake

次に、このRaspberry Piのカメラモジュールに対してOpenCVを用いることができるよう、「RaspiCam : C++ API for using Raspberry camera with/without OpenCv」をインストールします。まず、SourceForgeからraspicam-0.1.1.zip (129.5 kB)をダウンロードし、下記のコマンドでインストールします。

unzip raspicam-0.1.1.zip
cd raspicam-0.1.1
mkdir build
cd build
cmake ..
make
sudo make install
sudo ldconfig

このRaspiCamを用いると、Raspberry Piのカメラモジュールで取得した画像に対してOpenCVを利用できるので良さそうです。私は普段OpenCVを使っているわけではなく、RaspiCamも今回初めて触ったので、「良さそう」という程度しか言えないのですが。

次に、RGB LEDパネル用に私が用意したファイルを準備します。

cd
git clone https://github.com/neuralassembly/raspi_16x32RGBLED
cd raspi_16x32RGBLED
make

makeを実行した後、しばらく待つとビルドが完了します。画像ファイル表示用のimage2LEDmatrix、カメラモジュール表示用のcamera2LEDmatrixの2つの実行ファイルができています。 

さらに、Arduino用のserial2LEDmatrix.inoというC言語ファイルが存在します。このserial2LEDmatrix.inoをWindowsなどであらかじめArduinoに書き込んでおきましょう。 

このスケッチは、下図のように16x32x3バイトの階調(各階調は0~Fで表示)をシリアル通信で受け取り、「.」(ピリオド)を受け取ったタイミングでLEDパネルの内容を更新するように記述されています。



以下、image2LEDmatrixとcamera2LEDmatrixの使用法を解説してきます。

画像ファイルの表示 

image2LEDmatrixはSDカード上の画像をRGB LEDパネルに表示するプログラムです。練習兼動作検証用に書きました。

任意サイズの画像を与えることができます。画像の形式は、JPEGやPNGなど、OpenCVが読み込みに対応しているものです。動作モードは下記の2モードあります。

./image2LEDmatrix filename 0

末尾の0は省略することができます。こちらは下図のように画像の全体をスケーリングして表示します。なお、このページの画像は、見やすくするために全てRGB LEDパネルに紙をかぶせて撮影しています。


一方、下記の用に末尾に1をつけて起動すると、下図のように画像の左右または上下を捨て、なるべく画像を大きく表示します。

./image2LEDmatrix filename 1


Raspberry Piのカメラモジュールの映像の表示

カメラモジュールの映像を表示するには、下記のコマンドを実行します。

./camera2LEDmatrix

すると、下図のようにカメラモジュールの映像がRGB LEDパネルに表示されます。真面目に計測していませんが、体感で5fps以上は出ているのではないかと思います。

なお、フレームレートが低いのは、動作の安定化のためにwhileループ内でusleep関数によるウェイトを入れているためです。RaspiCam自体は約30fpsで映像を取得する能力がありますのでご注意ください。


やってみるとわかりますが(いや、やる前にわかるか)、解像度があまりにも小さいことと、LEDが明るすぎることとがあいまって、何が映っているかわからないことが多く、ちょっと厳しいです。

普通に周囲の映像を映すと、ほとんどのLEDがかなりの輝度で輝くので、1.0A以上の電流がパネルに流れてしまいます。

そのため、使いこなすには何らかの画像処理が必要そうです。せっかくOpenCVを使っているので、エッジ抽出、ビット反転、時間差分などを試したのですが、解像度の小ささから、何が起こっているのかわからず、イマイチでした。

何か面白い応用があれば、お知らせ頂ければ幸いです。

(おまけ)Pythonの場合

上で、C++とOpenCVでの例を紹介しましたが、その前にはPython + Pillowで試していました。この方法にはいくつか欠点があったため途中でやめてしまったのですが、メモとして記録を残しておきます。

準備

まず回路ですが、Python用いてArduinoとシリアル通信する場合は、こちらのstackoverflowにかかれているように、ArduinoのRESETとGNDの間に220μF程度のコンデンサを挟む必要があります。ただし、このコンデンサはスケッチ書き込み時は外してください。
(追記:すいません、コンデンサなしでも問題なく動くかもしれません。追試の必要あり)


次に、Raspberry Piでpipとpython-devとlibjpeg8-devをインストールします。

sudo apt-get update
sudo apt-get install python-pip python-dev libjpeg8-dev

次に、Pillow をインストールします。

sudo pip install pillow

以上の準備のもと、次に、RGB LEDパネル用に私が用意したファイルを準備します。

git clone https://github.com/neuralassembly/raspi_16x32RGBLED_Python

raspi_16x32RGBLED_Pythonの中に、画像ファイル表示用のimage2LEDmatrix.pyとカメラモジュールの映像表示用のcamera2LEDmatrix.pyとが入っています。

これらを用いるのは、C++版でも用いたserial2LEDmatrix.inoをArduinoに書き込んでおいてください。これは https://github.com/neuralassembly/raspi_16x32RGBLED に含まれています。

画像ファイルの表示

C++版と同様に、画像全体表示

python image2LEDmatrix.py filename 0

および、画像の切り出し表示

python image2LEDmatrix.py filename 1

に対応しています(末尾の0は省略できます)。画像ファイルのサイズも任意ですが、画像リサイズのアルゴリズム(PIL.Image.NEAREST、PIL.Image.BILINEAR、PIL.Image.BICUBIC、PIL.Image.ANTIALIAS)がイマイチなため、縮小後の画像があまり綺麗に表示されないことがあるのが欠点です(OpenCV版ではINTER_AREAを用いました)。

そのため、Python版ではWindowsのgimpなどで事前に画像を横32x縦16にリサイズしておいた方が良い場合があります。

Raspberry Piのカメラモジュールの映像の表示

カメラモジュールの映像を表示するには、下記のコマンドを用います。この辺りを参考にしました。

python camera2LEDmatrix.py

残念ながら、こちらはでは、2秒に1回程度しか映像が更新されません。そのため、Pythonをあきらめ、C++とOpenCVによる方法に移行したのでした。




「ラズパイ4対応 カラー図解 最新 Raspberry Piで学ぶ電子工作」、「実例で学ぶRaspberry Pi電子工作」、「Raspberry Piではじめる機械学習」を執筆しました。