HDRタイムラプス動画とHDR静止画で過去と現在の愛兎の様子を監視する(その2) #RaspberryPi #PiCamera #Python
kght6123
前回から間が空いてしまいましたが、露出を変えて連続で撮影する処理を作成します。
Pythonのfor文でループしつつ、露出を変えて何度も撮影するプログラムを、試作しましたが、
思った様に明るさが変わらないので、試行錯誤した結果、撮影だけのプログラムを別途作成し、別のPythonプログラムからパラメータを変えて連続で呼び出して、
明るさの異なる写真を5枚、取得する様にしました。
明るさが変わらない理由は不明で、シャッター速度・ISO感度を変更してsleep(2〜10秒)しても、2回目以降のループで明るさが変わらなくなります。
しかも、露出補正レベル(exposure_compensation)に関しては、1回目のループでも全く効果がありません。。。。
公式のドキュメントも確認しましたが、露出補正レベル、シャッター速度、ISO感度の使い方は間違っていない様です。
気持ち悪いですが、前述の様にPythonのプロセスを別にすれば、シャッター速度・ISO感度の変更が効いていたので、
撮影とプロセスを別にしました。
Pythonの撮影処理を別プロセスにするにあたって、前回のプログラムを、引数で撮影設定を変更できる様に修正しました。
画像サイズとISO感度、露出モード、シャッタスピード、露出補正レベル、出力ファイル名を指定できる様にしました。
05_capture_picamera_2.py
import sys
import io
import cv2
import numpy as np
from time import sleep
import picamera
# execute command
# python3 picapture.py 1296 972 1600 'sports' 10000 -25 photo90.jpg
# python3 picapture.py 1296 972 1600 'sports' 20000 0 photo91.jpg
# python3 picapture.py 1296 972 1600 'sports' 30000 25 photo92.jpg
# 引数を取得
args = sys.argv
# 撮影に関するパラメータを取得
width = int(sys.argv[1])
height = int(sys.argv[2])
iso = int(sys.argv[3])
exposure_mode = sys.argv[4]
shutter_speed = int(sys.argv[5])
exposure = int(sys.argv[6])
out_file_name = sys.argv[7]
sleep_time = 0.1
# Create the in-memory stream
stream = io.BytesIO()
with picamera.PiCamera(resolution=(width, height)) as camera:
camera.drc_strength = 'high'
camera.exposure_mode = exposure_mode
camera.iso = iso
camera.shutter_speed = shutter_speed
camera.exposure_compensation = exposure # 露出補正レベル -25~25
camera.sharpness = 100
camera.awb_mode = 'auto'
# Wait
sleep(sleep_time)
camera.capture(stream, use_video_port=False, format='jpeg', quality=85, bayer=True, thumbnail=(64, 48, 35))
# to OpenCV
# Construct a numpy array from the stream
data = np.fromstring(stream.getvalue(), dtype=np.uint8)
# "Decode" the image from the array, preserving colour
image = cv2.imdecode(data, 1) # 0=gray,
# OpenCV returns an array with data in BGR order. If you want RGB instead
# use the following...
#image = image[:, :, ::-1]
cv2.imwrite(out_file_name, image)
print ('ok. file='+out_file_name+',exposure='+str(camera.exposure_compensation)+',exposure_speed='+str(camera.exposure_speed))
pass
シャッタースピード、ISO感度を変更しながら、撮影するPythonプログラムを呼び出すプログラムを作成しました。
露光補正(exposure_list)は私の環境では効きませんが、一応、指定できる様にしています。
後は、cronで回す際の参考に、大まかな処理時間が知りたかったので、処理時間の計測のための処理を入れています。
だいたい、5枚の撮影処理に10秒ぐらいかかってます。
06_call_capture_picamera_2.py
import io
import time
import cv2
import subprocess as sp
import numpy as np
from datetime import datetime as dt
# execute command
# python3 picapture_hdr.py
start_t = time.time()
# 撮影パラメータ(5回分)
resolution = [1296, 972]
exposure_list = [0, 0, 0, 0, 0]
shutter_speed_list = [25000, 20000, 15000, 10000, 5000]
exposure_mode = ['sports', 'auto', 'auto', 'auto', 'auto']
iso_list = [1600, 800, 640, 500, 400]
file_name = 'picture'
ext_name = '.jpg'
timelapse_frame_count = 1
for i in range(timelapse_frame_count):
img_list = []
for j, exposure in enumerate(exposure_list):
# jpgファイル名を作成
file = file_name + str(j) + ext_name
# 撮影プログラムを呼び出すコマンドを作成
cmd = 'python3 05_capture_picamera_2.py ' + str(resolution[0]) + ' ' + str(resolution[1]) + ' ' \
+ str(iso_list[j]) + ' ' \
+ exposure_mode[j] + ' ' \
+ str(shutter_speed_list[j]) + ' ' \
+ str(exposure_list[j]) + ' ' \
+ file
print('[' + str(i) + '][' + str(j) + '] = ' + cmd)
# 撮影プログラムを実行
sp.check_output([cmd], shell=True)
# 撮影された画像ファイルを読みんで、追加
img_list.append(cv2.imread(file))
# 全体処理時間を出力
proc_t = time.time() - start_t
print ("finish time. {0}".format(proc_t) + "[sec]")
これで、HDR静止画を作るために必要な、明るさの異なる画像ファイルが撮影できる様になりました。
撮影の設定について説明させていただくと、基本的に薄暗い室内を撮影することを想定しています。
シャッタースピード(shutter_speed_list)とISO感度(iso_list)で明るさを調整し、明るさの異なる5枚の写真が撮れる様にしています。
露光モードはISO1600の時だけ、sportsにしています。(カメラの制限)
最後にこんな感じの5枚の明るさの異なる画像が撮れます。(写真に色々見えますが気にしない)
次は、OpenCVでHDR合成を行い、ffmpegでタイムラプス動画を作成します。