Raspberry Piの静止画撮影プログラム――picamera2で高解像度の写真を撮るコード例。
撮った写真、思ったより画質が低くありませんか。プレビュー設定のまま撮影してしまう典型的なミスから、ファイルの上書き防止まで、実際に動くプログラムの作り方を解説します。
目次
01「なんとなく撮れた」から「意図通りに撮る」へ
結論から言えば、picamera2で写真は簡単に撮れるが、「意図した解像度で」「上書きせずに」撮ろうとすると、もう一段階の理解が必要になる。プレビュー用の設定のまま撮影すると、画面表示と同じ低めの解像度で保存されてしまう。また、ファイル名を固定したまま繰り返し撮影すると、前の写真がどんどん上書きされてしまう。
実例として、picamera2で静止画を保存する方法を丁寧に解説した記事がある。picamera2でカメラの映像を静止画として保存する(Marupeke-IKD)では、create_still_configurationメソッドで取得したconfigは静止画モードのコンフィグであり、これをconfigureメソッドに設定した時点でPicamera2オブジェクトが「静止画モード」に切り替わると説明されている。プレビュー用の設定と静止画用の設定は別物であるという点が、意図通りの写真を撮る第一歩になる。
編集部見解:「動いた」と「意図通りに動いた」の間には、実は結構な距離がある。特にカメラプログラムは、画面上で一見正しく見えても、保存されたファイルを開いて初めて解像度の低さに気づく、ということが起こりやすい。撮影前に「今どの設定で撮ろうとしているか」を意識する癖をつけたい。
― YOFUKASI AI編集部
本記事では、picamera2を使った静止画撮影プログラムの基礎知識から、解像度とファイル名管理の仕組み、そして実際に複数枚を連番で撮影するプログラムの作り方までを、初心者を対象に解説する。
02静止画撮影プログラムの基礎知識
picamera2で静止画を撮影するコードは、大きく分けて「高レベルAPI」と「低レベルAPI」の2種類がある。手早く1枚撮りたいだけなら、高レベルAPIのstart_and_capture_file()を使うのが最も簡単である。
from picamera2 import Picamera2
picam2 = Picamera2()
picam2.start_and_capture_file("test.jpg")
この3行だけで撮影から保存までが完了する。実際に、この最小構成の書き方を紹介している記事もある。ラズパイカメラモジュールV3のファーストインプレッション(ラズパイダ)では、Picamera2はとても便利で単に撮影するだけならもっと端折ることもでき、Picamera2をインポートしてインスタンス化したあとstart_and_capture_fileを呼ぶだけの3行でOKだと紹介されている。
用語の整理
- 低レベルAPI:start()・configure()・capture_file()のように、各処理を個別に呼び出す書き方。細かい制御がしやすい。
- 高レベルAPI:start_and_capture_file()のように、複数の処理をまとめて行う書き方。手早く書けるがカスタマイズの余地は少ない。
- main / lores / raw:picamera2が内部で扱う3種類の画像ストリームの名前。通常の撮影では主に”main”を使う。
高レベルAPIには、複数枚を撮影するstart_and_capture_files()という関数も用意されている。Pythonライブラリ(Rasberry Piカメラ操作):Picamera2(KIYO)では、静止画の高レベルAPIとしてstart_and_capture_file(静止画撮影)とstart_and_capture_files(時間遅れごとの複数画像撮影)の2つがあり、name引数でファイル名を、delay引数で撮影前の待機時間を指定できると説明されている。
03解像度とファイル名管理の仕組み
撮影した写真の解像度は、プレビューウィンドウの大きさと連動してしまうことがある。実際にこの点でつまずいた経験が記録されている。Picamera2を使った写真の撮影(ノーザラントの研究室)では、撮影した写真のサイズがプレビューウィンドウと同じサイズになってしまい、サイズの大きな写真を撮影したい場合はプレビューウィンドウのサイズも大きくする必要が生じるが、Picamera2には写真撮影モードと動画撮影モードがあらかじめ準備されていると説明されている。つまり、プレビュー表示は小さいままにしつつ、撮影だけ高解像度で行いたい場合は、静止画専用の設定(create_still_configuration)を使う必要がある。
from picamera2 import Picamera2, Preview
import time
picam2 = Picamera2()
preview_config = picam2.create_preview_configuration(main={"size": (640, 480)})
still_config = picam2.create_still_configuration(main={"size": (4056, 3040)})
picam2.configure(preview_config)
picam2.start_preview(Preview.QTGL)
picam2.start()
time.sleep(2)
picam2.switch_mode_and_capture_file(still_config, "highres.jpg")
このように、プレビューは低解像度のまま表示しつつ、撮影の瞬間だけ高解像度の設定に切り替える、という書き方が実務でよく使われる。
ファイル名の上書き問題への対処
ファイル名を固定したまま撮影を繰り返すと、前の写真が上書きされてしまう。この問題への対処法も実例として紹介されている。同記事では、保存されるファイル名が固定だと複数枚撮影しても上書きされてしまうため、num変数を用意してその数字をファイル名にくっつけ、撮影のたびにnumを1ずつ増やすことで上書きを防ぐ方法が紹介されている。
連番(1, 2, 3…)の代わりに、撮影した日時を使ってファイル名を作る方法もある。
from datetime import datetimeのあと、filename = datetime.now().strftime("%Y%m%d_%H%M%S") + ".jpg"のように書けば、「いつ撮った写真か」がファイル名から一目で分かるようになる。長期間にわたって撮影するプログラムでは、こちらの方が管理しやすいことが多い。
04撮影方法(API・コマンドライン)の比較
静止画を撮影する方法には、Pythonのコード以外にコマンドラインという選択肢もある。用途に応じて整理する。
| 項目 | A. 高レベルAPI(start_and_capture_file) | B. 低レベルAPI(capture_file等) | C. コマンドライン(libcamera-still) |
|---|---|---|---|
| コードの短さ | 非常に短い | やや長い | コード不要 |
| 細かい制御 | 限定的 | 可能(解像度・タイミング等) | コマンドの引数の範囲内 |
| 他の処理との連携 | しづらい | しやすい(センサー値と組合せ等) | しづらい |
| 向いている場面 | 手早い動作確認 | 実際のプロジェクトへの組み込み | ターミナルでのその場確認 |
※コマンドラインでの撮影はlibcamera-still -o test.jpgのように実行する。Pythonプログラムとコマンドラインの使い分けはラズベリーパイ入門講座4(カメラモジュールを使用した撮影)(無料のオンラインパソコン教室)でも紹介されている。
動作確認の第一歩はコマンドライン(C案)で十分だが、センサーの値をきっかけに撮影するなど他の処理と組み合わせたい場合は、B案(低レベルAPI)でプログラムに組み込むのが実務的である。
05実践:連番ファイルで複数枚撮影するプログラムを作る5ステップ
ここでは「ボタンを押すたびに、上書きせず連番で写真を保存するプログラム」を作る手順を示す。
-
STEP1. カメラを起動し、静止画用の設定を準備する
Picamera2オブジェクトを作成し、静止画用の解像度設定を用意する。
例:picam2 = Picamera2(); still_config = picam2.create_still_configuration()を記述した。 -
STEP2. 撮影回数を記録する変数を用意する
撮影のたびに増やしていく変数(カウンター)を用意する。
例:count = 1を撮影ループの外側で定義した。 -
STEP3. ファイル名にカウンターを組み込む
文字列の連結で、カウンターの数字をファイル名に含める。
例:filename = "photo_" + str(count) + ".jpg"という形でファイル名を作成した。 -
STEP4. 撮影してカウンターを増やす
capture_file(filename)で撮影・保存し、その後カウンターを1増やす。例:picam2.capture_file(filename); count += 1を記述した。 -
STEP5. プログラム終了時にclose()でカメラを解放する
撮影がすべて終わったら、
picam2.close()を呼んでカメラのリソースを解放する。例:プログラムの最後にpicam2.close()を追加した。close()を省略していた際、次に別のプログラムでカメラを使おうとしたらエラーになったため、この行を追加した(編集部想定シナリオ)。
ここで作成した仕組みに、時間指定の自動撮影(タイムラプス的な使い方)を組み合わせることも可能である。time.sleep()を組み合わせたループにすれば、一定間隔での連続撮影プログラムに発展させられる。
06注意点・よくある誤解
プレビュー用の設定のまま撮影すると、プレビュー画面と同じ比較的低い解像度で保存されてしまう。高解像度で撮影したい場合は、create_still_configuration()を使った静止画専用の設定に切り替える必要がある。
ファイル名を固定したまま繰り返し撮影すると、前の写真が上書きされてしまう。連番やタイムスタンプをファイル名に含めることで、意図せず過去の写真を消してしまう事態を防げる。
プログラムを終了しても、close()を呼んでいないとカメラのリソースが正しく解放されず、次にカメラを使おうとした際にエラーになることがある。撮影処理の最後には明示的にclose()を呼ぶ習慣をつけておきたい。
07FAQ
参考文献
- Marupeke-IKD「picamera2でカメラの映像を静止画として保存する」note, 2023年. https://note.com/marupeke296/n/n0c0ae7c9ef3f
- ラズパイダ「ラズパイカメラモジュールV3のファーストインプレッション」ラズパイダ, 2024年. https://raspida.com/cameramodule-v3-1st-impression/
- KIYO「Pythonライブラリ(Rasberry Piカメラ操作):Picamera2」note, 2023年. https://note.com/kiyo_ai_note/n/nf45b058afdfa
- ノーザラントの研究室「Picamera2を使った写真の撮影」ノーザラントの研究室, 2023年. https://erectro.sendai-hs-union.net/2023/02/picamera2-%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9/
- 無料のオンラインパソコン教室「ラズベリーパイ入門講座4(カメラモジュールを使用した撮影)」無料のオンラインパソコン教室. https://www.telln.com/lesson/2024/04/23/
- 本文中の具体的な原因特定エピソードは、断りのない限り編集部想定シナリオに基づく想定であり、実測データではありません。
関連記事(内部リンク)
該当なし(本記事はRaspberry Pi・picamera2がテーマであり、内部リンクプールはArduino関連記事のみで構成されているため、無理な挿入は行っていません。)
コメント