M5Stack UnitV2 で静止画を撮影する(http方式)

今回紹介するのはM5Stack UnitV2で静止画像をキャプチャする方法です。

UnitV2を起動してhttp://10.254.239.1/video_feedを叩けばストリーミング映像が取得できますが、静止画ではありません。

静止画を取るパスがないか探しましたがどうにもないようなので強引にsever_core.pyを改造してみました。

まず78行目付近にcurrent_imgというグローバル変数を追加しました。

1
2
3
4
# ~~~ server_core.py 78行目付近~~~
pipe_img_rx_queue = queue.Queue(10)
current_img = None #<= ココ
pipe_msg_rx_queue = queue.Queue(10)

そして203行目付近でvideo_feed用のキューに画像を詰め込んでるところの前でcurrent_imgにも画像を入れます。

1
2
3
4
5
6
# ~~~ server_core.py 203行目付近~~~
if pipe_img_rx_queue.qsize() >= 10:
continue
current_img = frame #<= ココ
pipe_img_rx_queue.put(b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

最後に/image_shotというパスに対応したメソッドを作成します。switchFunctionを呼んでcamera_streamにモードを変更して映像の取得を開始させます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# ~~~ server_core.py 596行目付近~~~
@app.route('/image_shot')
def image_shot():
# global current_img, process, client_is_connected, process_name
global process, client_is_connected
client_is_connected = True
if not process is None:
process.stdout.flush()
time.sleep(1)

if process_name != "camera_stream":
switchFunction('camera_stream', "")
time.sleep(3)
else:
switchFunction('camera_stream', "")

pipe_img_rx_queue.get()
pipe_img_rx_queue.task_done()

return Response(current_img, mimetype='image/jpeg')

改造したserver_core.pyはこちらです。これをUnitV2と接続したPCにダウンロードしてきます。

M5Stack UnitV2への適用方法

  1. PC => UnitV2へserver_core.pyをコピー

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # @PC UnitV2にsshでログイン
    $ ssh m5stack@unitv2.py

    # @UnitV2 /dev/nullのpermissionを変えないとscpできない
    $ sudo chmod 666 /dev/null

    # @PC PCからUnitV2へscpでファイルをもっていく
    # コピー先を/media/sdcardにしたのは~/だとm5stackユーザーが直で置けないため、m5stackユーザ用のディレクトリをどこかに作ってもいい
    $ scp <ファイルを置いたディレクトリ>/server_core.py m5stack@10.254.239.1:/media/sdcard/

    # @UnitV2 一応置き換える予定のserver_core.pyをリネームしておく
    $ sudo mv ~/payload/server_core.py ~/payload/_server_core.py

    # @UnitV2 server_core.pyを~/payload/に持っていく
    $ sudo cp /media/sdcard/server_core.py ~/payload/

  2. M5Stack UnitV2を再起動する。USBを再接続でもいいと思いますが、私はsudo haltしてからUSBを抜き差ししています。

  3. M5Stack UnitV2が再起動したら http://10.254.239.1/image_shot を叩くと画像が表示されます。

コピーするのがめんどくさい場合は、sshでUnitV2にログインしてインストールされているviなどを使って当該箇所を書き換えてください。sever_core.py内のcurrent_imgという変数が使われている箇所を持ってくれば動くはずです。

課題

かなり強引に実装したので課題点が結構あります。

  • 画像サイズを自由に変えたい
  • ストリーミングの処理に乗っかるのではなく、単体の静止画取得メソッドを作りたい
  • shot_image.pyみたいなファイルにして直接ファイルを実行させたい
  • ブラウザを叩いてから戻ってくるまで数秒待つので、もっと速くしたい

また、間違っているところがあるかもしれないのでその場合はお問い合わせかgithubのプルリクで知らせてください。