2013年11月2日土曜日

Raspberry Pi用カメラモジュールおよび赤外線カメラPi NoIRの映像をandroidで表示してみた

0. はじめに

Raspberry Pi用の赤外線カメラPi NoIRが発売されました。
赤外線カメラは使ったことがないので興味があり、早速注文してみました。

既存のカメラと同じくraspistillコマンドなどで使えるのですが、
今回、その映像をmjpg-streamerで配信し、androidで見てみることにします。
なお、本ページの内容は、Pi NoIRだけでなく通常のRaspberry Pi用カメラでも全く同様に成り立ちます。

なお、2016年4月、Raspberry Piのカメラモジュールのバージョン2が発売になりました。こちらでも本ページのプログラムは動作するのですが、NOOBS1.9.0までのRaspbianでは映像の向きが上下逆転してしまいます。次のRaspbianが出るまで待つことをお勧めします。上級者の方には「sudo rpi-update」でカーネルを最新にすれば正常動作することをお知らせしておきます。


1. 新しい方法


ここから解説するのは、下記のサイトで紹介されている方法です。
解像度640x480、30fpsで高画質で動作するのでおすすめの方法です。

1.1 カメラモジュール対応のmjpg-streamerのインストール

まず、あらかじめraspi-config でカメラを有効にしておいてください。
そして、下記の要領で、カメラモジュール対応のmjpg-streamerをインストールします。


sudo apt-get update
sudo apt-get install libjpeg8-dev cmake
git clone https://github.com/jacksonliam/mjpg-streamer.git mjpg-streamer
cd mjpg-streamer/mjpg-streamer-experimental
make
cd
sudo mv mjpg-streamer/mjpg-streamer-experimental /opt/mjpg-streamer

インストールが完了したら、下記の内容をユーザーpiのホームディレクトリ/home/piにstart_steam.shという名前で保存します。なお、このスクリプトでは解像度640x480、フレームレート15fpsでmjpg-streamerを起動します。お好みで設定を変更してください(解像度640x480、30fpsまでは安定動作を確認しました)

#!/bin/bash
 
if pgrep mjpg_streamer > /dev/null
then
  echo "mjpg_streamer already running"
else
  LD_LIBRARY_PATH=/opt/mjpg-streamer/ /opt/mjpg-streamer/mjpg_streamer -i "input_raspicam.so -fps 15 -q 50 -x 640 -y 480" -o "output_http.so -p 9000 -w /opt/mjpg-streamer/www" > /dev/null 2>&1&
  echo "mjpg_streamer started"
fi

次に、このスクリプトを/etc/rc.localに記述することで、自動起動します。そのために、エディタで/etc/rc.localを編集するのですが、その際、管理者モードでないと保存できませんので注意してください。viで編集する場合は下記のようにsudoをつけて起動します。

sudo vi /etc/rc.local

もともと、「exit 0」という行が最後に記されているのですが、その手前に下記のように1行追記します。

(中略)

sh /home/pi/start_steam.sh

exit 0  # ←この行はもともとある行

以上でRaspberry Piを再起動すると、mjpg-streamerが自動で起動します。


1.2 android側アプリで閲覧

PCのブラウザで、Raspberry Piが動いているIPアドレスの9000ポートを見ると(http://xx.xx.xx.xx:9000/)、
映像が配信されていることがわかります。このポート番号は、上のスクリプトstart_stream.shの内部で決定されています。

この映像をandroidで受け取るには、手前味噌ですが簡単MJPEGビューアを使うと簡単です。
このアプリのソースはこちらにあります。

アプリを起動したら、メニューから「設定」を選択し、下図のように、解像度を640x480に、「ポート番号」を9000に(キーボードで記述)、コマンドを「?action=stream」に設定してください。


設定を保存すると下記のように、Raspberry Piのカメラから配信された映像がandroid上に表示されます。
なお、この映像は暗い部屋で人形にテレビのリモコンの赤外線を当てて撮影しました。


以上で目的は達成です。

冒頭で紹介した「Raspberry Piで学ぶ電子工作」ではこのRaspberry Piとカメラモジュールの組み合わせをキャタピラ式模型に搭載し、iPadなどのタブレットのウェブブラウザから映像を見ながら操作する、という演習を取り入れています。下記の内容紹介動画のおよそ1:38からその様子が示されています。



若干映像が詰まるところが見られますが(およそ1:57)、これはRaspberry Piと用いたWifiドングルの相性の問題と考えています。

「Raspberry Pi 2 + kernel 4.1 / 4.4 系列で5GHz対応WifiドングルGW-450Dを動かした」 を参考にGW-450Dを用いるとこの「映像の詰まり」は解消されるのですが、kernelの再構築が必要なので、書籍では紹介できませんでした。

以上です。


なお、以下に記すのは古い内容なので読み飛ばして頂いて構いません。


2. 古い方法

ここから先は、このエントリを執筆した2013年11月当時の古い方法です。今この方法を用いる必要性はないのですが、記録として残しておきます。

2.1Raspbian側の準備

まず、あらかじめraspi-config でカメラを有効にしておいてください。

次に、OSを最新にします。

sudo apt-get update
sudo apt-get upgrade

さらに、ファームウェアを最新にします。 これを実行しておかないと後でmjpg-streamerを起動するときに「ERROR opening V4L interface: Interrupted system call」というエラーがでます。
(2014.6.5追記:なお、2014.5.6のRaspbianを用いたところ、このプロセスは不要になっていました)

sudo rpi-update

なお、アップデートを実行すると、Raspberry Piの起動時の「Mounting local filesystems」の際にmmcblk0に関するエラーが出て起動しなくなる場合があります。その場合、こちらに関連情報がありますが、SDカードを変更すれば状況が改善する場合があります。

私の場合、Transcend SDHC 8GB(class 10)で起動しなくなったので、古いTranscend SDHC 8GB(class 2)に変更したところ、問題が解決しました。

2.2 Video4Linuxの有効化

次に、Rapsberry PiのカメラをVideo4Linuxで用いるために、こちらを参考にVideo4Linuxを有効にします。まず、以下を実行。

wget http://www.linux-projects.org/listing/uv4l_repo/lrkey.asc && sudo apt-key add ./lrkey.asc

次に、/etc/apt/sources.listの末尾に下記の行を加えます。

deb http://www.linux-projects.org/listing/uv4l_repo/raspbian/ wheezy main

そして、以下を実行します。

sudo apt-get update
sudo apt-get install uv4l uv4l-raspicam

2.3 mjpg-streamerのインストール

こちらを参考に、mjpg-streamerをインストールします。

まず、インストールに必要なライブラリやヘッダなどをインストールします。

sudo apt-get install libjpeg8-dev libv4l-dev
sudo apt-get install imagemagick

ヘッダにリンクを貼ります。

sudo ln -s /usr/include/linux/videodev2.h /usr/include/linux/videodev.h

次に、mjpg-streamerの最新のソースをダウンロードするため、subversionをインストールします。

sudo apt-get install subversion

そしてmjpg-streamerのソースをダウンロードします。

svn co https://svn.code.sf.net/p/mjpg-streamer/code/mjpg-streamer mjpg-streamer

そして、以下のようにmakeします。

cd mjpg-streamer
make

エラーが出ずにビルドが完了すれば次に進みます。

2.4 mjpg-streamerの起動

mjpg-streamerをビルドしたディレクトリで作業します。

まず、Video4Linuxを有効にします(このコマンドはどのディレクトリでもOK)。なお、無効にするには pkill uv4lを実行します。この例は解像度320x240、フレームレート10fpsです。

uv4l --driver raspicam --auto-video_nr --width 320 --height 240 --framerate 10

そして、mjpg-streamerを起動します。やはり解像度320x240、フレームレート10fpsを指定しています。

export LD_LIBRARY_PATH="$(pwd)"
LD_PRELOAD=/usr/lib/uv4l/uv4lext/armv6l/libuv4lext.so ./mjpg_streamer -i "input_uvc.so -d /dev/video0 -r 320x240 -f 10 -no_dynctrl" -o "output_http.so -w ./www"

色々試してみたところ、フレームレートを大きくすると不安定になるようで、mjpg-streamerが落ちます。私の環境では解像度320x240、フレームレート10fpsでは安定して動きますので、どこまでいけるか色々試してみてください。

2.5 android側アプリで閲覧

PCのブラウザで、Raspberry Piが動いているIPアドレスの8080ポートを見ると(http://xx.xx.xx.xx:8080/)、
映像が配信されていることがわかります。

この映像をandroidで受け取るには、手前味噌ですが簡単MJPEGビューアを使うと簡単です。
このアプリのソースはこちらにあります。

アプリを起動したら、メニューから「設定」を選択し、下図のように、解像度を320x240に、ポート番号を8080に設定します。

設定を保存すると下記のように、Raspberry Piのカメラから配信された映像がandroid上に表示されます。
なお、この映像は暗い部屋で人形にテレビのリモコンの赤外線を当てて撮影しました。




2.6  mjpg-streamerの自動起動

さて、動作が確認できたところで、必要な方はRaspberry Piが起動するときにmjpg-streamerが自動で起動するようにしておきましょう。以下、Raspberry Piでの操作です。

mjpg-streamerのディレクトリが/home/pi/mjpg-streamerであるという前提で話を進めます。

cd ~/mjpg-streamer

このディレクトリに、start-mjpg-streamer.shというファイルを作成し、下記の内容を記述します。エディタはviでもnanoでも、お好みのもので構いません。

#!/bin/sh

uv4l --driver raspicam --auto-video_nr --width 320 --height 240 --framerate 10

cd /home/pi/mjpg-streamer

export LD_LIBRARY_PATH="$(pwd)"

LD_PRELOAD=/usr/lib/uv4l/uv4lext/armv6l/libuv4lext.so ./mjpg_streamer -i "input_uvc.so -d /dev/video0 -r 320x240 -f 10 -no_dynctrl" -o "output_http.so -w ./www"

次に、このスクリプトを/etc/rc.localに記述することで、自動起動します。そのために、エディタで/etc/rc.localを編集するのですが、その際、管理者モードでないと保存できませんので注意してください。viで編集する場合は下記のようにsudoをつけて起動します。

sudo vi /etc/rc.local

もともと、「exit 0」という行が最後に記されているのですが、その手前に下記のように1行追記します。

(中略)

sh /home/pi/mjpg-streamer/start-mjpg-streamer.sh &

exit 0  # ←この行はもともとある行

保存したらRaspberry Piを再起動してみてください。mjpg-streamerが自動で起動しているはずです。お疲れ様でした。



「カラー図解 最新 Raspberry Piで学ぶ電子工作」、「実例で学ぶRaspberry Pi電子工作」を執筆しました。