ラズベリーパイとカメラモジュールを組み合わせることで、手軽に写真や動画を撮影することができます。
長時間の記録では、光量の少ない夜間の写真撮影が必要になることがあるでしょう。それ以外にも夜間のタイムラプス、星空撮影などでは限られた光量を最大限まで活かすため、シャッタースピードを長くする「長時間露光」が欠かせません。
今回使用するカメラモジュールは安価な以下の製品です。
RasTech Raspberry Pi カメラモジュール Raspberry Pi カメラ 500万画素 Raspberry Pi4B/3B+/3B/2B+/ZERO1….
コマンドでは、以下のように手軽に長時間露光による写真撮影ができます。
sudo raspistill -o test.jpg -ss 5000000
しかし、Pythonをはじめとしたプログラムでは少しだけコツが必要です。ちなみにこのコマンドではシャッタースピードを5秒に設定して撮影しています。単位はマイクロ秒ですから、1秒 = 1,000,000マイクロ秒となります。
Pythonによる長時間露光(シャッタースピード調整)
Pythonで長時間露光撮影のプログラムは以下のようになります。
from picamera.camera import PiCamera
from fractions import Fraction
# PiCameraインスタンスを生成
camera = PiCamera()
# フレームレートを6分の1に設定
camera.framerate = Fraction(1,6)
# シャッタースピードを設定(単位:マイクロ秒 = 100万分の1秒)
camera.shutter_speed = 6000000
# カメラ設定待ち
time.sleep(30)
# 露出の自動設定を無効化
camera.exposure_mode = 'off'
# 撮影&保存
camera.capture('test.jpg')
camera.close()
太字で示したように、PiCameraインスタンスであるcameraのshutter_speedを設定することでシャッタースピードを設定できます。上記プログラムでは、6000000マイクロ秒(6秒)を設定しています。
写真(静止画)を撮影するのであればこれだけでも機能しそうなものなのですが、残念ながら機能しません。なぜならシャッタースピードはフレームレートの値によって上限が定められているからです。デフォルトのフレームレートは30fpsに設定されており、この場合には30分の1秒以上のシャッタースピードを設定できません。フレームレートを変更しない場合には、シャッタースピードが33333マイクロ秒くらいで頭打ちになります。
解像度およびセンサーモードに応じた制限もありますが、あえて指定しない限り意識する必要はありません。フレームレートを設定しなかった場合の写真のプロパティを確認すると以下のようになっています。
シャッタースピードをいくら長くしても、デフォルトのフレームレートである30fpsではシャッタースピードは1/30秒が上限です。「静止画ならフレームレートは関係ないのでは?」なんてカメラ知識がない僕は思ってしまいます。しかし、少なくともRaspberryPiのカメラモジュールをPiCameraで操作する際には、静止画でもフレームレートの設定が必要です。
長時間露光する場合には最も遅い6分の1fpsに設定します。ちなみにシャッタースピードの上限は約6秒で、フレームレートを更に小さくしても6秒以上のシャッタースピードは設定できません。V2モジュールではシャッタースピードが10秒、フレームレートは10分の1まで設定できるはずなのですが、手持ちのカメラでは6秒ちょいが限界です。純正品なら10秒いけるのかも?
camera = PiCamera()
camera.framerate = Fraction(1,6)
camera.shutter_speed = 5000000
time.sleep(30)
camera.exposure_mode = 'off'
Fractionクラスは分数を手軽に表現することができます。第一引数は分子を、第二引数は分母を指定することで分数を分数のまま扱うことができます。
ラズベリーパイのカメラモジュールは基本的に多くの設定をデフォルトでいい具合にしてくれています。これを無効化する設定がexposure_mode = ‘off’の設定です。その前にsleep(30)がありますが、これはカメラの起動およびシャッタースピードの変更の反映待ちです。
ラズベリーパイのカメラモジュールは起動に時間がかかります。
カメラを起動してすぐに撮影するとひどく暗くなることがあります。設定変更後も同様で、少し待ち時間を作ってやると安定した画質で撮影ができます。
ここでは30秒待っていますが、実際にはもっと短くても問題ありません。
ギリギリの時間を見極めたい場合には、実際に撮影を繰り返してみると良いでしょう。
ループ処理で長時間の記録
ループ処理で一定時間ごとに撮影したり、一定の条件に合致した際に撮影する場合があります。
その際には、先ほど紹介したプログラムのうち以下の処理を先頭に記述します。
import time
import datetime
from picamera.camera import PiCamera
from fractions import Fraction
INTERVAL = 300 # 撮影間隔(秒)
SHUTTER_SPEED_IN_DARK = 6000000 # 暗所でのシャッタースピード(6秒)
SHUTTER_SPEED_IN_LIGHT = 0 # 明るい場所でのシャッタースピード(0を指定すると自動調整)
FRAMERATE_IN_DARK = Fraction(1,6) # 暗所でのフレームレート(1/6fps)
FRAMERATE_IN_LIGHT = 30 # 明るい場所でのフレームレート(30fps)
# 時間に応じてカメラの設定を変更するメソッド
def set_exposure(camera):
# 現在時刻の時間の整数値を取得
hour = int(datetime.datetime.now().strftime("%H"))
if 7 < hour < 17:
# 7時以降17時以前であれば明るい場所用のフレームレートとシャッタースピードを設定し露出を自動制御
camera.framerate = FRAMERATE_IN_LIGHT
camera.shutter_speed = SHUTTER_SPEED_IN_LIGHT
camera.exposure_mode = 'auto'
else:
# 7時以前17時以降であれば暗所用のフレームレートとシャッタースピードを設定し露出を固定
camera.framerate = FRAMERATE_IN_DARK
camera.shutter_speed = SHUTTER_SPEED_IN_DARK
camera.exposure_mode = 'off'
# PiCameraインスタンスを生成
camera = PiCamera()
# 露出を設定
set_exposure(camera)
# ループ内で300秒間隔に写真を撮影する
while True:
try:
camera.capture('test.jpg')
set_exposure(camera)
time.sleep(INTERVAL)
except KeyboardInterrupt:
camera.close()
break
以降はループ処理のなかでcamera.capture(ファイル名)の処理を必要に応じて呼び出すだけでOKです。夜間はシャッタースピードを伸ばし、昼間は0(Auto)にするような設定をしても良いでしょう。
明るさに応じて設定を変更する
シャッタースピードを長くすると、暗所や夜間の光量が少ない環境下での撮影に適している反面、明るい時間帯は写真が真っ白になってしまいます。そのため実環境下では、周囲の明るさに応じて設定を変更する必要が出てきます。カメラモジュールは自動制御機能が備わっており、内部的には輝度などを検出しているのですが、それを手軽に取り出すことはできません。
撮影した写真からパラメータを取り出すなど、カメラモジュールを光量センサー代わりに使うにはスマートな方法が見当たりません。本格的に長期間の記録を行う場合には別途光量センサー(1個数百円)を購入すると良いでしょう。(光量センサーの商品例)
もし数日~数十日程度の記録であれば、単純に日の出と日の入り時間を見てざっくりと制御すれば十分です。
一例を以下に示します。
import time
import RPi.GPIO as GPIO
from picamera.camera import PiCamera
from fractions import Fraction
LED_PIN = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED_PIN, GPIO.OUT)
camera = PiCamera()
camera.framerate = Fraction(1,6)
camera.shutter_speed = 5000000
time.sleep(30)
camera.exposure_mode = 'off'
<span style="color: #d32f2f; font-size: 80%;"># LEDを点灯して撮影し、撮影後に消灯</span>
GPIO.output(LED_PIN, GPIO.HIGH)
camera.capture('test.jpg')
GPIO.output(LED_PIN, GPIO.LOW)
GPIO.cleanup(LED_PIN)
camera.close()
300秒間隔で写真撮影を行い、昼間(7時~17時)は露出を自動設定、夜間(17時~7時)は長時間露光するシンプルなプログラムです。
LEDをフラッシュ代わりに使用するとなお良い
ラズベリーパイでプログラムや電子工作に入門する方へ向けた第一歩として定番のLEDを光らせるプログラム。
みなさんも一度くらいは経験したことがあるのではないでしょうか?
あのLEDをカメラの撮影時だけ点灯させることで、簡易的なフラッシュ代わりに使用できます。
ラズベリーパイの出力電圧は低く、しっかりとした照明を焚くにはリレー等の使用が必要です。しかし、長めのシャッタースピードとLEDを組み合わせると暗所での撮影が非常に安定します。
LEDだけ配線を伸ばして撮影したい対象物に隣接させて点灯すれば、長時間露光と組み合わせて記録には十分な写真が撮影できます。
例えば以下のようなプログラムです。
特別な処理はなく、単純に長時間露光撮影に加えてLEDを点灯させているだけです。
まったく照明のない暗所でも、小さなLED照明と5秒程度のシャッタースピードで記録には十分な写真を撮影することができます。
ただし、LED照明自体が小さいので広い場所で遠くのものを撮影するには不向きです。
狭所で近いものを撮影する場合に有効といえます。
もしフラッシュを自作したいのであれば明るいLEDや100Vの照明をリレー制御で点灯させたり、USBライトをラズベリーパイのUSBポートに接続して、USBポートの通電を制御してオンオフする方法が最もお手軽です。
特にUSBポートを使用する方法は追加部材も不要で、ライト自体も100均やホームセンターで手に入ります。
また、カメラモジュール自体を暗所撮影に対応したものに買い替えるのも一つの方法でしょう。
Raspberry Pi用OSOYOO IR-CUTカメラ、500万画素 OV5647モジュール搭載 昼夜モード自動切り替え、赤外線ナイ…