picamera2でカメラの映像を静止画として保存する(Raspberry Pi, python)

 picamera2でカメラの映像を表示できるようになると、やはりそれを保存したくなってきます。保存する対象は「動画(video)」と「静止画(image)」があります。今回は静止画について見て行きましょう。

手っ取り早く保存する

 静止画をファイルとして保存する方法は実はいくつかあります。これ正直picamera2の静止画保存をちょっとややこしくしている感がある気がしてます(^-^;。多分一番分かりが良さそうかなと思う方法は、Picamera2.capture_fileメソッドを使う方法です:

from picamera2 import Picamera2
import time

pc2 = Picamera2()
pc2.start()

# カメラをスタートした後安定するまで少し時間を置いた方が良いです
time.sleep( 1 )

# 現在のカメラの映像を静止画(jpg)として保存
# 保存先はPythonコードがあるフォルダ
pc2.capture_file( "capture_image.jpg" )

time.sleep( 1 )

# 別パスにPNGとして保存
# フォルダは予め作っておかないとだめ
pc2.capture_file( "./images/capture_image.png" )

 Picamera2.start()で撮影を開始した後、カメラが反応して起動安定するまでちょっと待ちます。その後に、

pc2.capture_file( "capture_image.jpg" )

capture_fileメソッドを呼ぶと現在の映像を静止画として保存してくれます。引数には保存したいファイルの相対パス(もしくはフルパス)を渡します。相対パスにした場合はカレントディレクトリがルートになります。

 ファイルフォーマットはJPEG、PNG、BMP、GIFで、拡張子で判断してくれます。

プレビュー画面が保存されるわけではない

 上のコードをターミナルから実行すると、数秒後にアプリが終わってしまします。その間プレビュー画面などは表示されません。これ、不思議に思う人もいるかもしれません。だって何も表示されていないのに映像はちゃんと保存されているんですから。そう、ここで保存されているのはプレビュー画面のスクリーンショット的な物では無くて、カメラのセンサーが捉えている映像そのものなんです。

 試しに先のコードでプレビュー画面を小さく表示してみます:

from picamera2 import Picamera2
import time

pc2 = Picamera2()

#プレビューを表示
pc2.start_preview( True, width =  300, height =  200 )
pc2.start()

# カメラをスタートした後安定するまで少し時間を置いた方が良いです
time.sleep( 1 )

# 現在のカメラの映像を静止画(jpg)として保存
# 保存先はPythonコードがあるフォルダ
pc2.capture_file( "capture_image.jpg" )

time.sleep( 1 )

# 別パスにPNGとして保存
# フォルダは予め作っておかないとだめ
pc2.capture_file( "./images/capture_image.png" )

 横300、縦200の小さいプレビューウィンドウを表示しています。でも保存されるファイルはこれに関係なくカメラの解像度そのもののサイズになっているはずです。つまりプレビューのウィンドウ設定と保存されるファイルとには関係がありません。

保存解像度を変更する

 capture_fileメソッドは何も設定しない場合は現在のカメラのデフォルト解像度で保存します。でも別の解像度で保存したい事もままあります。保存する映像の解像度を変更するには「Stream Configuration」というコンフィグパラメータ群を変更する必要があります。とりあえずコードで見てみましょうか:

from picamera2 import Picamera2
import time

pc2 = Picamera2()

# 静止画(still)モードのコンフィグを取得
config = pc2.create_still_configuration()

# 解像度を変更
config["main"]["size"] = ( 160, 120 )

# Stillモードのコンフィグを設定
# (stillモードにモード変更)
pc2.configure( config )

# カメラをスタートした後安定するまで少し時間を置いた方が良いです
pc2.start()
time.sleep( 5 )

# 現在のカメラの映像を静止画(jpg)として保存
pc2.capture_file( "capture_image.jpg" )

 まずはこの1行:

# 静止画(still)モードのコンフィグを取得
config = pc2.create_still_configuration()

これはカメラの静止画モード(Stillモード)の現在のコンフィグ一覧を取得しています。create_still_configurationメソッドの戻り値は辞書形式になっているコンフィグデータです。その中に"main"というキーがあります。この"main"の値も辞書になっています。その中に"size"というキーがあり、そこに解像度をタプルで設定します:

# 解像度を変更
config["main"]["size"] = ( 160, 120 )

上で["main"]["size"]となっているのは、辞書の中に辞書が入れ子になっているからなんですね。

 こうして変更したコンフィグを再設定するのが次の1行:

# Stillモードのコンフィグを設定
# (stillモードにモード変更)
pc2.configure( config )

configureメソッドに変更したコンフィグ辞書ごと設定すると、解像度含めすべての設定が反映されます。ここで重要な事。最初にcreate_still_configurationメソッドで取得したconfigは静止画モードのコンフィグです。これをconfigureメソッドに設定した時点でPicamera2オブジェクト(pc2)は「静止画モード」に切り替わります。

 後はcapture_fileメソッドを呼び出すと指定した解像度のファイルになります。

mainって何だ?

 上の"main"というキー。これとても重要です。実はラズパイのカメラには「3つの出力(stream)」が用意されています。それが"main"、"lores"そして"raw"です。

 main streamは一番主要な出力で、画像として扱えるRGBなフォーマット等をサポートした出力をしてくれます。普通はこのstreamを使います。lores(おそらく low resolutionの略)streamは低解像度でちょっと特殊な出力フォーマットになっています。そしてraw streamはカメラのセンサーが捉えた情報をそのまま得る事が出来ます。ただし一般的には扱いにくいフォーマットです。

 という事で、あまり複雑な事をしないのであればmain streamのみを意識するで十分だと思います。

解像度を下げるメリット

 保存解像度をコンフィグで小さくすると、全体的な保存のパフォーマンスが良くなります。画素数が下がるのでファイルサイズが小さくなりますし、実はセンサーからメモリに書き込む量も劇的に減ります。僕のカメラの場合、静止画モードのデフォルトではセンサーフォーマットが9152×6944という巨大サイズになります:

センサーで受信した情報はラズパイ上の集積回路に流れ、そこでメモリにデジタルデータとして書き込まれます。当然ならがこの書き込み量が少ない程パフォーマンスは良くなるわけです。保存解像度を800×600に設定すると、

センサーフォーマットが1280×720になりました。メモリ書き込み量はこれで実に先程の最大サイズの1.4%(70分の1程)にまで下がります。そりゃ速いってもんです。

 必要な解像度を適切に設定する事が大切という事ですね。

終わりに

 今回はpicamera2で静止画を保存する一つの方法を見てみました。他にも幾つか保存方法がありますが、それは追々必要になった時に紹介します。ファイルを保存できるようになると「プレビューを見て、ボタンを押したらパシャッと保存」というカメラらしい使い方がしたくなってきます。そこで次回はGUIを表示させてその辺りを実践してみようと思います。

ではまた(^-^)/

この記事が気に入ったらサポートをしてみませんか?