USBカメラの映像をボードからサーバへ転送=Armadillo-IoT試用レポート3

Armadillo-IoT G3をお借りした目的の一つは、携帯回線を簡単に使用できるか、という点でしたが、これはレポート2で確認できました。

もう一つの目的は、ボードとしての実力、汎用性を確認することです。

そこで、USBカメラで撮影してサーバにアップロードする、という方法で実力を計ろうと思います。

カメラは汎用的なWEBカメラを選択

汎用性も評価したいので、以下の理由からエレコムのUSBカメラを使うことにしました。

  • 実用的な接続手段。
    → USB接続。
  • ドライバ等の手間を最小限に。
    → UVC(USB Video Class)のカメラなのでドライバ要らず。
    (ドライバがLinux(Debian)に導入済みなので手間がかからない)
  • 入手性。
    → テストした型番が生産中止になっても、代替品が入手できる見込みが高い。
  • 安価。
    → 約2000円。

ELECOM WEBカメラ UCAM-C0220FBWH

Amazonで見る : https://amzn.to/3nrNuJC

USBコネクタにカメラを接続すると、USBドライバとUVCドライバに認識され、以下の様なメッセージが出ます。


usb 1-1: new high-speed USB device number 2 using ci_hdrc
uvcvideo: Found UVC 1.00 device UCAM-C0220F (056e:7016)
...

これにより /dev ディレクトリに video0やvideo1といった名前で定義されますので、lsコマンドで確認します。


# ls -l /dev/video*
crw-rw---- 1 root video 81, 0 Dec 25 12:36 /dev/video0

/dev/video0 を指定すればこのUSBカメラが使用されます。

キャプチャ(撮影)コマンドは fswebcam

今回は fswebcam というキャプチャソフトを使わせて頂きます。

これは、指定したカメラをOpenして指定サイズで静止画撮影し、jpegファイルに落としてくれるソフトです。
静止画で良い場合はこれで十分ですね。

以下の様にインストールします。
(尚、この段階ではSIM通信料節約のため、LANケーブルを繋いであります)


# sudo apt-get install fswebcam
Reading package lists...
...
Setting up fswebcam (20140113-1) ...
Processing triggers for libc-bin (2.19-18+deb8u10) ...

40秒くらいで終わりました。

早速キャプチャしてみましょう。


# fswebcam -d /dev/video0 -r 1024 --jpeg 95 101.jpg
--- Opening /dev/video0...
Trying source module v4l2...
/dev/video0 opened.
No input was specified, using the first.
Adjusting resolution from 1024x-1 to 1280x1024.
--- Capturing frame...
Captured frame in 0.00 seconds.
--- Processing captured image...
Setting output format to JPEG, quality 95
Writing JPEG image to '101.jpg'.

-d で使用するカメラを指定し、-rでサイズ(縦ピクセル数)を指定し、–jpegで圧縮率を指定し、最後にファイル名を指定します。

2~3秒かかりました。
1280×1024もあるとキャプチャ時間も圧縮時間もそれなりにかかりますね。

サイズを352×288に落としたら1秒弱くらいになりました。

おそらく、カメラを開きっぱなしにして、ファイル化に要する時間を少なくする工夫したプログラムを作ればもう少し改善できるでしょう。

画像ファイルをサーバにアップロード

今回は、この記事を書いているサーバに画像ファイルをアップロードします。

sshというセキュリティ保護された接続でファイルを転送するコマンド scp を使用します。

毎回パスワードを入力していては評価になりませんので、あらかじめssh接続できるようにsshのキーを書いたファイルを実機に置いておきました。
これで、セキュリティを気にせずscpコマンドが働いてくれます。


# scp 101.jpg ebi:www/wp/test

(念のため…)同様のテストを行いたい場合は、サーバ(ebi:www/wp/test)は自分で用意する必要があります。サーバ持ってなくても、google driveとかでもできるらしいので、挑戦してみてください。

ブラウザのアドレスバーに以下の様に入力すると、アップロードされたファイルが確認できます。


https://team-ebi.com/test/101.jpg

ピンぼけしててすみません。
時間を計るなら時計を撮影するのがベストと思ったのですが、ちょっと近すぎました。

コマンドでサーバからダウンロードするときは以下の様にします。


# scp ebi:www/wp/test/101.jpg recv.jpg 

実測速度は30KB/s前後。

275KB前後の画像ファイルが8秒~12秒でアップロードされました。
(ファイル処理の時間やサーバ側の処理時間も含まれます)

3Gの通信速度は下り最大3.6Mbps/上り最大384kbpsなので、期待を裏切らない結果と言えるでしょう。

余談:上り384kbpsに対して、30KB/sで十分とはどういう意味?と思いましたか?

30KB/sというのは、1秒間で30×1024バイト=転送する速度です。
仮に1バイト=8ビットとした場合、240kbpsとも書けないこともありませんが、実際には1バイトを8bitだけで転送することはできないので、もっと数字が大きくなります。
(例として、最もシンプルなシリアル通信の場合、1バイトを9bitで転送できるので、30KB/sは270kbpsです。)

384kbpsというのは、データを通す経路の速度です。
1秒間で384×1024ビット流すという速度です。

その経路にデータを流す為に、データとデータがくっつかないように、衝突しないようにルールを定めて流していきますので、隙間なく流すことはできません。
また、他人のデータと区別する為にパケット化したりするので、実際のデータは大きくなります。
例えば、隙間を20%空けて、パケット化その他で20%大きくなった場合、転送可能なデータ量は384kbpsの60%≒秒間230キロビット≒29KB/sです。

そういった制約の中、30KB=240キロビットを384kbpsの回線に流すということは、約63%の効率でデータを転送したということです。

その為、期待を裏切らない結果を得た、と考えたわけです。

尚、ダウンロード時間は同ファイルサイズで2秒強、137.3KB/sでした。

ファイル処理時間も見逃せない

より現実的な評価を行うため、キャプチャ → アップロード → キャプチャ → アップロード…
と繰り返すcam.shというスクリプトを作りました。


FNUM=101

	FDIR=

FNAME=`printf "%03d" $FNUM`
scp ebi:www/wp/test/$FNAME.jpg start.jpg 

while [ $FNUM -le 110 ] ; do

	FNAME=`printf "%03d" $FNUM`
	echo $FNAME ---------------- step 1
	fswebcam -d /dev/video0 -r 1024 --jpeg 95 $FDIR$FNAME.jpg
	echo $FNAME ---------------- step 2
	scp $FDIR$FNAME.jpg ebi:www/wp/test
	echo $FNAME ---------------- step 3

FNUM=`expr $FNUM + 1`
done

scp ebi:www/wp/test/$FNAME.jpg end.jpg 

上記スクリプトファイルをカレントディレクトリに置きます。

通常、ファイルを作る時はエディタを開いて入力したり、転送コマンドでコピーしたりしますが、面倒な場合は、以下の様にリダイレクトすると楽です。

  • cat > cam.sh と入力。(この後に入力するコードをcam.shに入れよ、というコマンド)
  • cam.shの中身を入力。コピペでもOK。
  • Ctrl+Dを押す。(リダイレクトの終わりを示す)

cat > cam.sh
 

以下の様に入力すると実行できます。


sh cam.sh

しかし、これを実行すると、トータル時間が前述の時間と一致しません。

原因はキャプチャしたものをファイルとして保存するのに時間がかかっていたこと、でした。

それに、このスクリプトをずっと実行していたらDISK(eMMC)にずっと書き込み続けることになるので、実用面を考えると、良くありません。

そこで、RAMDISKを用意し、そこにファイルを書き出すようにしました。

RAMDISKは次のように作ります。

sudo mkdir /mnt/ramdisk
sudo mount -t tmpfs -o size=10m /dev/shm /mnt/ramdisk

RAMDISKに書き出すようにするため、cam.shのFDIRを書き換えます。


FNUM=101

	FDIR=/mnt/ramdisk/
#	FDIR=

FNAME=`printf "%03d" $FNUM`
scp ebi:www/wp/test/$FNAME.jpg start.jpg 

while [ $FNUM -le 110 ] ; do

	FNAME=`printf "%03d" $FNUM`
	echo $FNAME ---------------- step 1
	fswebcam -d /dev/video0 -r 1024 --jpeg 95 $FDIR$FNAME.jpg
	echo $FNAME ---------------- step 2
	scp $FDIR$FNAME.jpg ebi:www/wp/test
	echo $FNAME ---------------- step 3

FNUM=`expr $FNUM + 1`
done

scp ebi:www/wp/test/$FNAME.jpg end.jpg 

これで、1280×1024のカメラ画像が約11秒周期でアップロードできるようになりました。

サイズが352×288なら約2秒周期です。

期待通りの結果が得られて、一安心です。
これで、現実的な提案ができますね。

ところで、Armaillo-IoTには今回の3Gの他に4G(LTE)版もあるんですよね…
(4Gならもっと早くなるはず!)