About

本サイトについて

趣味で開発したプログラムや開発メモを載せています。
ソースコードはGithubで公開しつつ、なるべく後から分かるように解説に努めてますので、
誰かのお役に立てれば嬉しいです。

プロフィール

kght6123

佐賀県出身で1985年生まれ。
三重県四日市市在住のシステムエンジニア。家庭を大事にしたい2児の父。

kght6123.page

HDRタイムラプス動画とHDR静止画で過去と現在の愛兎の様子を監視する(その3) #RaspberryPi #PiCamera #Python

2022-10-01T11:54:24.872Z

前回は明るさの異なる5枚の写真を撮影しましたが、今回はHDR画像とタイムラプス動画を作成します。

タイムラプス動画の作成には、ffmpegを利用します。

ffmpegは出来れば、ハードウェアエンコーダ(h264_omx)が使える方がより良いです。

OpenCVのHDRの作成方法には「Debvec」「Robertson」「Mertenes」の3パターンがあります。

今回は、露光時間が不要な「Mertenes」を利用します。

出来れば、露光時間を与えた方がより良い結果になるそうですが、十分、綺麗だったので、今回は露光時間は渡していません。

HDR合成した結果は、ffmpegでタイムラプス動画を作成する際に必要な、4桁の連番を付与してファイル出力します。

基本的にOpenCVの公式サイトのそのままですが、コントラスト・彩度・露出のパラメータを設定できる余地を残しています。

07_create_hdr.py

print('[' + str(i) + '] create HDR start.')

# HDR(Mertens)の初期化
merge_mertens = cv2.createMergeMertens(contrast_weight=1.0, saturation_weight=1.0, exposure_weight=0.0)

# Mertensを用いて露光を統合
res_mertens = merge_mertens.process(img_list)

print('[' + str(i) + '] create HDR MergeMertens complete.')

# データ型を8ビットに変換
res_mertens_8bit = np.clip(res_mertens * 255, 0, 255).astype('uint8')

print('[' + str(i) + '] create HDR encode 8bit complete.')

# ファイルに書き出し(ffmpegに渡すために4桁の連番をファイル名に付与)
hdr_file = "fusion_mertens_" + '{0:04d}'.format(i + 1) + ".jpg"
cv2.imwrite(hdr_file, res_mertens_8bit)

print('[' + str(i) + '] create HDR end. file = ' + hdr_file)

ffmpegで、タイムラプス動画を作成します。

ビデオコーデックはハードウェアエンコーダ(h264_omx)を使い、ビットレート(-b:v)は「4M」を明示的に指定します。

出力は開始日時(start_dt)ごとに行いたいので、あらかじめ、プログラムの先頭でシステム日時を取得しておきます。

08_create_timelapse.py

# タイムラプス動画作成
cmd = 'ffmpeg -f image2 -r 3 -i fusion_mertens_%04d.jpg' + \
  ' -an -vcodec h264_omx -pix_fmt yuv420p' + \
  ' -b:v 4M -profile:v 100 timelapse_' + start_dt + '.mp4'

print('create Timelapse start. cmd = ' + cmd)
sp.check_output([cmd], shell=True)
print('create Timelapse end.')

この一連の処理で、HDR画像とタイムラプスを作ることができます。

前回の明るさを変えて撮影した、5枚の画像をHDR合成すると、HDRっぽい白飛びや黒つぶれが少なく、コントラストが低い感じになります。

今回は、愛兎の監視に利用しますが、HDR合成しているので風景などコントラストが高いものの長時間撮影に利用すると、綺麗かもしれません。

HDR合成した画像

次回は、Microsoft Onedriveに作成したHDR静止画と、タイムラプス動画をアップロードします。