Picamera2を使った写真の撮影

プレビューウィンドウの設定

libcameraでカメラが動くことが分かったら、Pythonで使いたい。カメラ周りのことは全て Picamera2 で実現できます。嬉しいことに Picamera2 は Raspberry Pi にデフォルトでインストールされています。

では、カメラの映像をプレビューする簡単なプログラムを組んでみましょう。

from picamera2 import Picamera2, Preview

picam2 = Picamera2()
picam2.start_preview(Preview.QTGL)
picam2.start()

実行するとこんな感じになります。

shellには赤文字で、ずらずらと出てくるのですが、エラーメッセージではありません。

3行目で、Picamera2のインスタンスを作成し、4行目でそのインスタンスのプレビューウィンドウを表示し、5行目でカメラをスタートさせます。

これで、カメラの映像がリアルタイムに画面に表示されるはずです。たった4行で延々とプレビューを表示し続けてくれ流のです。簡単ですね!

プレビューウィンドウは、オプションを設定することで、色々調整できます。

サイズと位置の調整

先ほどの4行プログラムはすべで初期値のままでしたが、表示する位置やサイズを調整する場合はそのオプションを指定します。

from picamera2 import Picamera2, Preview

picam2 = Picamera2()
picam2.start_preview(Preview.QTGL, x = 200, y = 100, width = 800, height = 600)
picam2.start()

実行すると、ちょっと右下(200,100)の位置にプレビューウィンドウが表示され、大きさも800×600の大きさになりました。

左右反転・上下反転・180度回転

次の例は、左右反転したプレビューです。鏡の代わりになりますね!

from picamera2 import Picamera2, Preview
from libcamera import Transform

picam2 = Picamera2()
picam2.start_preview(Preview.QTGL, x = 200, y = 100, width = 800, height = 600, transform=Transform(hflip=1))
picam2.start()

ちゃんと扉が左右逆になっています。

更に上下反転もさせて、結果的に180ど回転した映像を表示させた例です。

from picamera2 import Picamera2, Preview
from libcamera import Transform

picam2 = Picamera2()
picam2.start_preview(Preview.QTGL, x = 200, y = 100, width = 800, height = 600, transform=Transform(hflip=1,vflip=1))
picam2.start()

写真の撮影

では、早速写真を撮影してみましょうか。ここで紹介するのは、もちろんFPV-TANK用のプログラムなので、ただ写真を撮るのではなく、プレビューウィンドウを表示させつつ、任意のタイミングで、写真を撮影してみたいと思います。

タイミングの指示は色々方法が考えられますが、ここではラズパイのUSB端子に接続したゲームコントローラーを使います。

ゲームコントローラーからの入力

次のプログラムは、ゲームコントローラーの1つ目のボタンが押されたら、「ボタンが押された!」と表示するプログラムです。

import pygame

pygame.init()
joy = pygame.joystick.Joystick(0) # joystickのインスタンスを作成
joy.init() # joyの初期化

while True:
    if pygame.event.get(): #もし、何かイベントが起こったら
        if joy.get_button(0): #もし、joyの1つ目のボタンが押されてたら
            print("ボタンが押された!")

これで、ゲームコントローラーの入力を捉える方法が分かりましたね。ついでに2つ目のボタンも拾ってみましょうか。

import pygame

pygame.init()
joy = pygame.joystick.Joystick(0) # joystickのインスタンスを作成
joy.init() # joyの初期化

while True:
    if pygame.event.get(): #もし、何かイベントが起こったら
        if joy.get_button(0): #もし、joyの1つ目のボタンが押されてたら
            print("Aボタンが押された!")
        if joy.get_button(1): #もし、joyの2つ目のボタンが押されてたら
            print("Bボタンが押された!")

実行するとこんな感じ。

写真の撮影

では、Picamera2 のプレビューと組み合わせて、Aボタンを押したら、写真の撮影をするプログラムを組んでみましょうか。

from picamera2 import Picamera2, Preview
import pygame

picam2 = Picamera2()
picam2.start_preview(Preview.QTGL)
picam2.start()

pygame.init()
joy = pygame.joystick.Joystick(0) # joystickのインスタンスを作成
joy.init() # joyの初期化

while True:
    
    if pygame.event.get():
        if joy.get_button(0):
            print("写真を撮りました!")
            picam2.capture_file("test.jpg")
実際に撮った写真

これで、プレビューウィンドウを表示し、任意のタイミングで写真を撮影できるようになりました。ただし、保存されるファイル名が「test.jpg」のため、複数枚写真を撮影しようとしても上書きされてしまいます。上書きされないようにちょっと工夫して、ファイル名に数字を付けてみましょうか。

from picamera2 import Picamera2, Preview
import pygame

picam2 = Picamera2()
picam2.start_preview(Preview.QTGL)
picam2.start()

pygame.init()
joy = pygame.joystick.Joystick(0) # joystickのインスタンスを作成
joy.init() # joyの初期化

num = 1

while True:
    
    if pygame.event.get():
        if joy.get_button(0):
            print(num,"枚目の写真を撮りました!")
            picam2.capture_file("test" + str(num) + ".jpg")
            num = num + 1

numという変数を用意して、その数字をファイル名にくっつけました。numは数字なのですが、ファイル名は文字列にしなければいけないので、保存するときは、数字を文字列に変換する str 関数を用いています。これで、何枚写真を撮っても上書きされなくなりました。

さて、写真を見るとわかるのですが、撮影した写真のサイズは、プレビューウィンドウと同じサイズになります。サイズの大きな写真を撮影したい場合は、プレビューウィンドウのサイズも大きくしなければいけないのですが、モニター画面のサイズを超える大きさの写真が撮りたい場合もあるし、プレビューは小さくて良いから、写真は大きなサイズで撮りたいという欲求が起こります。

写真撮影モードにスイッチして、写真を撮る

実は、Picamera2 には写真撮影モードと、動画撮影モードが予め準備されています。

では、写真撮影モードで写真を撮ってみましょうか。

from picamera2 import Picamera2, Preview
import pygame

picam2 = Picamera2()
picam2.start_preview(Preview.QTGL)
picam2.start()

pygame.init()
joy = pygame.joystick.Joystick(0) # joystickのインスタンスを作成
joy.init() # joyの初期化

num = 1
full_res = picam2.sensor_resolution
picam2.still_configuration.size = (full_res)

while True:
    
    if pygame.event.get():
        if joy.get_button(0):
            print(num,"枚目の写真を撮りました!")
            picam2.switch_mode_and_capture_file("still", "test" + str(num) + ".jpg")
            num = num + 1

13行目で、カメラで撮ることのできる最大サイズを調べ、full_res という変数に代入します。
14行目で、写真撮影モードで撮る写真のサイズを、full_res つまり最大にしています。
20行目で、モードを「still」モードにチェンジして、写真を撮影するように変更してみました。

これで撮った写真がこちらです。

ワイドカメラなので、周囲の余計な部分まで入っています。ブラウザでは分かりにくいかもしれませんが、ピクセルサイズは 4608×2592です。

最初に撮ったプレビューは、センターの部分だけ切り取っていたことが分かりますね。

以上、写真撮り方講座でした。

HDRとか、露出とか、シャッタースピードとかの調整方法も分かり次第ここに続けて書いて行こうと思います。

コメント

タイトルとURLをコピーしました