以下を参考にした。ほぼ丸写し。
高ダイナミック・レンジ — OpenCV-Python Tutorials
画像は以下から。
High-dynamic-range imaging - Wikipedia
参考にしたサイトでは3種類の手法を紹介しているがここではmertens融合だけ。リストは露光時間の長い方から並べてある。
import cv2 import numpy as np img_fn = ["img0.jpg", "img1.jpg", "img2.jpg", "img3.jpg"] img_list = [cv2.imread(fn) for fn in img_fn] merge_mertens = cv2.createMergeMertens() res_mertens = merge_mertens.process(img_list) res_mertens_8bit = np.clip(res_mertens*255, 0, 255).astype('uint8') cv2.imwrite("hdr0.jpg", res_mertens_8bit)
各画像の位置がズレてる。位置ズレを修正してくれる関数があるのでそれを使う。
import cv2 import numpy as np img_fn = ["img0.jpg", "img1.jpg", "img2.jpg", "img3.jpg"] img_list = [cv2.imread(fn) for fn in img_fn] mtb = cv2.createAlignMTB() mtb.process(img_list, img_list) merge_mertens = cv2.createMergeMertens() res_mertens = merge_mertens.process(img_list) res_mertens_8bit = np.clip(res_mertens*255, 0, 255).astype('uint8') cv2.imwrite("hdr1.jpg", res_mertens_8bit)
更にズレが大きくなった。一番暗い画像を外してやってみる。
良さそう。
4枚全部使いたいのでphaseCorrelateで位置合わせしてみた。
はじめ一番明るい画像と残りの3枚を突き合わせてみたところ、一番暗い画像が大幅にずれてしまったので、以下のコードでは露光時間の近いもの同士で比較している。
import cv2 import numpy as np img_fn = ["img0.jpg", "img1.jpg", "img2.jpg", "img3.jpg"] img_list = [cv2.imread(fn) for fn in img_fn] for i in range(len(img_fn) - 1): gry1 = cv2.cvtColor(img_list[i], cv2.COLOR_BGR2GRAY) gry2 = cv2.cvtColor(img_list[i+1], cv2.COLOR_BGR2GRAY) gry1 = np.array(gry1, 'float32') gry2 = np.array(gry2, 'float32') (x, y), z = cv2.phaseCorrelate(gry1, gry2) M = np.float32([[1, 0, -x], [0, 1, -y]]) h, w = gry2.shape img_list[i+1] = cv2.warpAffine(img_list[i+1], M, (w, h)) merge_mertens = cv2.createMergeMertens() res_mertens = merge_mertens.process(img_list) res_mertens_8bit = np.clip(res_mertens*255, 0, 255).astype('uint8') cv2.imwrite("hdr3.jpg", res_mertens_8bit)