chakokuのブログ(rev4)

テック・コミック・DTM・・・ごくまれにチャリ

Node-RED + libcamera-jpegを組み合わせて、撮影できる仕組みを作る

背景:Amazon Recognitonを使うには、顔が映ったJPEGが必要
課題:Node-RED+libcamera-jpegを組み合わせて、RPiカメラでプレビューと撮影できるようにする
結論:動くには動いた
問題点:libcamera-jpegの撮影にかかる時間が長くてプレビュー更新周期が長い(使い物にならないぐらいに更新が遅い)。RPiカメラのアプリがあるなら、どういう実装になっているのか調べたい
方針見直し:レビュー用画像の連続撮影は、libcamera-jpegを使わずpicamera2 を使う

詳細:
bullseyeから?カメラ操作は、libcamera-jpegを使うらしい。RPiにRPiカメラを装着するだけで、撮影可能にはなった。
単純に撮影するだけなら、以下でJPEG画像が取得できる

libcamera-jpeg -o test.jpg

どんな画像になっているのかプレビューは必須なので、リアルタイムでサムネイルなりを常時表示しつづけ、適切な画像になったらシャッター操作をする。。。つもりだったが、いろいろ問題が出た。最終的には以下のノード構成となった。
分かりづらいですが、画面右側がプレビュー画像で、左側が撮影画像、実際は撮影しておらず、プレビューから撮影用ファイルにコピーしているだけです。Node-REDでもExcecノードでcpコマンドを実行しているだけ。

問題その1:libcamera-jpegが一枚写真を撮影するのに1秒程度かかる。だから、プレビューの更新周期が1秒ぐらいになって、非常に間延びする。これはかなりイラっとなる。
ー>パラメータを組み合わせてなんとか短くしたが、、やはり撮影に時間がかかりすぎる。連続撮影してプレビューするのに無理があって、ストリーミングするぐらいの実装にしないとだめなのかも。撮影中も実装を工夫すると画像データがリアルタイムで抜けるのかもしれない
現時点での撮影用Execノードのコマンド(採用しないけど記録のために記載)

libcamera-jpeg --nopreview  --immediate  -t 1 --flush --width 320 --height 240  --brightness 0.2  -o /tmp/preview.jpg  

問題その2:プレビューでカメラデバイスは使いっきりになり、シャッター押して本物の画像を取ろうとしても、デバイスがビジーでエラーになる。
ー>撮影ボタンが押された時のプレビューデータを撮影データとしてしまう

Node-REDからプレビュー・撮影アプリを呼び出してしまうか?

■追記
libcamera-jpegは機能が充実しているのだが、一枚撮影するだけの場合、遅い。Pythonのライブラリとして使えるpycameraの方が早いのではないか。バイナリよりPythonの方が早いというのは、PycameraのライブラリがC/C++で書かれたバイナリだからではないか?と想像しますが、Gitでソースを見ていないので半分妄想です。libcamera-jpeg以外の撮影手段もあると思われ、他の手段で軽く撮影できれば、プレビュー画面のfpsが稼げると思っています。
例えば、、以下のサンプルコードの場合、秒3枚ぐらい撮影可能。だから、Node-REDからは以下のプログラムを起動する。非同期的にpreview.jpgを更新する。撮影ボタンが押されたら、preview.jpgをphoto.jpg等にコピーして、解析に使う。(どうにかして止める手段も必要だが)

#!/usr/bin/python3

import datetime
from picamera2 import Picamera2

camera = Picamera2()
config_capture = camera.create_still_configuration()
camera.configure(config_capture)
camera.start()
while True:
   print(datetime.datetime.now())
   camera.capture_file("preview.jpg")

どんどんNode-REDから離れていくので、美しくないアプローチなのだが、、速度が出ないのでしょうがない。
気づき:撮影時にマウスを使うのではなく、押しボタンを使うべき。マウスでinjectノードをクリックして撮影というのは慣れないだろう。