ラズパイカメラを使って連続撮影&fbiコマンドでCUI画面のフレームバッファに直接表示する方法。SSH経由でもOK!

前回の記事で、ラズパイのカメラモジュールを使ってサクサクと写真が撮れることがわかりましたので、さらに色々と試してみます!

今回は、連続撮影CUI環境でも画像を表示する方法を紹介します。

 

raspistillコマンドで連続撮影

USB接続のWebカメラでfswebcamコマンドだと、15秒ほど待たないと次の写真が撮れませんでした。raspistillコマンドでどれくらいの頻度で撮影できるか確かめてみます。

1回の撮影にかかる時間をtimeコマンドで計測してみます。”-t”オプションで最小値の1を指定しました。

$ time raspistill -t 1 -o t1.jpg
real 0m1.069s
user 0m0.030s
sys 0m0.140s

結果は、約1秒。なかなかの速さです。

次に連続撮影を試してみます。
連続撮影するスクリプト(stcam-n.sh)を書いて、シェルの実行時間を計ります。※縦横サイズを800×600にしています。

#!/bin/bash
for n in `seq 0 5` ; do
	raspistill -o ./ser-${n}.jpg -w 800 -h 600 -t 1
done

実行結果です。

$ time sh stcam-n.sh
real 0m7.749s
user 0m0.180s
sys 0m0.740s

6枚撮影して7.75秒。途中書込に時間がかかったのか少し遅れる事がありましたが、概ね1秒強で撮影できており、Webカメラよりかなり速く連続撮影できることがわかりました。

今回はフルサイズで撮影すると重すぎたので800×600で撮影しましたが、途中2枚ほど写真に横線が入っていました。処理能力が低いラズパイzeroで、大きな写真を高速&連続で撮影するとエラーが入ってしまうようなので注意が必要です。

 

CUIの画面に表示してみる

raspistillでの撮影中に、HDMI接続したディスプレイの画面にプレビューが表示されていたので、これはきっとCUI画面でも撮った画像を表示できるに違いない!と思って探したらありました!

ポイントは、フレームバッファに直接描画です。

※後で知ったのですが有名な話なんですね。。。勉強になりました。

 

fbiコマンドを使ってシェルで表示

ラズパイに直接キーボードを接続できる場合には、フレームバッファに直接描画してイメージを表示するコマンド「fbi」が使えます。スライドショーで表示したり編集できたりとなかなかの優れものです。

インストール方法

$ sudo apt-get install fbi

取り急ぎ確認したい場合は、画像ファイルを指定します。

$ fbi ss.png

表示中にキーを押す事で様々な操作が可能です。よく使うものを列挙します。

  • q 終了
  • j 次のイメージ
  • k 前のイメージ
  • a 自動ズーム(画面に収まるように自動的に拡大縮小)
  • + 拡大
  • - 縮小

※fbiの他にもpythonのpygameを使った表示方法などもありましたが、ラズパイzeroだとpythonの起動に5秒ぐらいかかってあまり実用的ではなかったので止めました。

 

参考

  1. How do I display images without starting X11?
  2. View images without gui

 

ssh接続でHDMIディスプレイに画像を表示する

ラズパイzeroの貴重なUSBポートをキーボードに占有されるのはもったいないし、sshで作業する方が楽です。

そこで、ラズパイにつないだHDMIディスプレイにssh経由のfbiコマンドで画像を表示する方法を紹介します。

ポイントは2つです。

  • バーチャルコンソールを“-T”で指定する。
  • 管理者権限で実行する。

仮想ターミナル(/dev/tty1)に表示する場合は、以下のようにします。

$ sudo fbi -T 1 hoge.jpg

※デフォルトでは/dev/fb0にマッピングされるのでdevice framebufferを直接指定しなくても表示されます。複数の出力先があり明示的に指定したい場合には“-d”オプションで、/dev/fb0 などを指定します。

終了するときは“q”を送るか、pkillでプロセスを切ります。

sudo perl -e '$chr="q"; require "sys/ioctl.ph";open($hTTY, ">", "/dev/tty1");ioctl($hTTY, TIOCSTI(), $chr)'

もしくは、

sudo pkill fbi

(※pkill無理矢理終了なので、オススメは上記の“q”を送る方法です。後述します)

なお、表示中にコンソールを切り替える(Ctrl + Alt + F1〜F6)と、プロセスと標準入力が切り離されてしまいうまく終了できなくなる場合があるので注意が必要です。

 

“q”キーを送るスクリプト(ssh経由)

fbi実行時には必ず使うので、先ほどの”q”を送るスクリプトを作成して、パスが通る所に置いておくと操作が快適になります。

パスが通った適当な場所にファイルを作り、中に先ほどのperlのスクリプトを貼り付けて保存します。

$ vi ~/local/bin/send-key-q
 sudo perl -e '$chr="q"; require "sys/ioctl.ph";open($hTTY, ">", "/dev/tty1");ioctl($hTTY, TIOCSTI(), $chr)'

実行権を与えて、

$ chmod +x ~/local/bin/send-key-q

~/.bashrcの最後に以下の1行を追記してパスを通します。

export PATH=$PATH:$HOME/local/bin

読み込み直して有効化します。

$ . ~/.bashrc

ssh経由のfbiコマンドで/dev/tty1に画像を表示した場合は、send-key-q を実行することで安全に終了することができるようになります。

 

どんなキーでも送れるようにしてみた。

せっかくなので、拡大縮小その他色々できるように、引数にキーを与えて実行できるようなスクリプト send-key-any を書いてみました。

#!/bin/bash
if [ $# -ne 1 ]; then
	echo "Useage: `basename $0` [key]"
	exit 
fi
sudo perl -e '$chr="'$1'"; require "sys/ioctl.ph";open($hTTY, ">", "/dev/tty1");ioctl($hTTY, TIOCSTI(), $chr)'

任意の文字を引数に指定すれば送る事ができます。

$ send-key-any q

※なお、ラズパイ本体の方でログインしておかないと終了以外のコマンドは受け付けない(実際はログイン画面が表示されるだけ)ので注意が必要です。

 

参考

  1. Raspberry Pi(raspbian)でSSHからHDMI接続中の画面にXを使わず画像を表示する。
  2. raspberry pi に ssh接続でキーストロークを送信する仕組みがわかりません、どうやって検索や調べ物をすれば良いのでしょうか?
  3. ioctlについて調べてみた

 

おまけ。HDMI出力のOn/Offをコマンドで切り替える

SSH経由で作業している時など、仮想コンソール(tty1など)にしばらくキーボード入力がないと、ラズパイのHDMI出力が停止してしまいます。

そんな時はコマンドで簡単にOn/Offを切り替えることができます。

HDMI出力ON(hdmi-on)

sudo sh -c "echo 0 > /sys/class/graphics/fb0/blank"

HDMI出力OFF(hdmi-off)

sudo sh -c "echo 1 > /sys/class/graphics/fb0/blank"

blankの切り替えなので0と1の動作には注意して下さい。

これらもよく使うので、それぞれスクリプトとして(hdmi-on, hdmi-off)、パスが通った場所に設置する(~/local/bin/に置く)と作業が楽になります。

 

参考
Raspberry Piでフレームバッファを使ったデジタルサイネージ

 

まとめ

CUI環境でもフレームバッファに直接描画して画像などを見る事ができました。
ラズパイZeroなどデスクトップが重くて実用的ではない環境でも有効な方法です!

デスクトップ環境が無くてもさくさく使える方法なので、これから応用の夢が広がります(^o^)

みなさま、よいラズパイ生活を(・∀・)/〜