OpenCVの使い方21 ~ 画像ピラミッド2
今回は前回の画像ピラミッドを応用した2つの画像のブレンディング処理について紹介する。
1. ピラミッド画像によるブレンディング
以下のりんごとオレンジの画像を左半分と右半分でブレンディングする。
ピラミッド画像によるブレンディング処理は、
使用する2枚の画像のガウシアンピラミッド画像を例えば6段階(512x512→16x16)を用意する。
ガウシアンピラミッドから5段階のラプラシアンピラミッド画像を生成する。(6段階目の16x16はガウシアンピラミッド画像)
次に各段階ごとに得られたラプラシアンピラミッドをりんごは左半分、オレンジは右半分をつなぎ合わせた画像を作る。
最後にガウシアンピラミッドの6段階目の16x16の左側がりんご、右側がオレンジの画像をアップサンプリングして、5段階目の半分りんご、半分オレンジのラプラシアンピラミッドを加算する処理を元の画像512x512まで繰り返す。
2. ガウシアンピラミッドとラプラシアンピラミッドの生成
りんごの画像を読み込みsrc
、オレンジの画像を読み込みsrc2
とする。6段階のガウシアンピラミッドはG = cv2.pyrDown(G)
とfor文を用いて再帰的に適用することで6段階のガウシアンピラミッドgpA, gpBが得られる。
G = src.copy() gpA = [G] for i in range(6): G = cv2.pyrDown(G) gpA.append(G) G = src2.copy() gpB = [G] for i in range(6): G = cv2.pyrDown(G) gpB.append(G)
りんごのガウシアンピラミッドgpA
を表示してみると、段階iが進むごとに低解像画像になっていることがわかる。
plt.figure(figsize=(9,6)) for i in range(6): plt.subplot(2,3,i+1) plt.imshow(gpA[i])
次にラプラシアンピラミッドを生成する。低解像度の画像をアップサンプリングしていくため、最も解像度が低いgpA[5]:16x16から処理を開始する。
# generate Laplacian Pyramid for A lpA = [gpA[5]] for i in range(5,0,-1): GE = cv2.pyrUp(gpA[i]) L = cv2.subtract(gpA[i-1],GE) lpA.append(L) plt.figure(figsize=(9,6)) for i in range(6): plt.subplot(2,3,i+1) plt.imshow(lpA[i])
最も低解像度の16x16以外は輪郭抽出したような画像になっている。
オレンジの画像についても同様に処理する。
lpB = [gpB[5]] for i in range(5,0,-1): GE = cv2.pyrUp(gpB[i]) L = cv2.subtract(gpB[i-1],GE) lpB.append(L)
3. ラプラシアンピラミッドのつなぎ合わせと再構成
りんごのラプラシアンピラミッドの左側lpA[:,0:int(cols/2)]とみかんのラプラシアンピラミッドの右側lpB[:,int(col/2):]をnp.hstack()
を用いて段階ごとにつなぎあわせる。つなぎ合わせた結果はLS
に格納する。
LS = [] for la,lb in zip(lpA,lpB): rows,cols,dpt = la.shape ls = np.hstack((la[:,0:int(cols/2)], lb[:,int(cols/2):])) LS.append(ls) plt.figure(figsize=(9,6)) for i in range(6): plt.subplot(2,3,i+1) plt.imshow(LS[i])
再構成は最も解像度が低い16x16を32x32にアップサンプリングした画像と32x32のつなぎ合わせたラプラシアンピラミッドの画像を加算し、加算した画像を64x64にアップサンプリングし、64x64のつなぎ合わせたラプラシアンピラミッドを加算する。これを元の画素数の512x512になるまで繰り返す。
ls_ = LS[0] plt.figure(figsize=(12,8)) for i in range(1,6): ls_ = cv2.pyrUp(ls_) ls_ = cv2.add(ls_, LS[i]) plt.subplot(2,3,i) plt.imshow(ls_)
以下再構成の各段階での画像を確認すると、粗いブレンディング画像から細かいブレンディング画像に変化している様子がわかる。
最後にピラミッド画像を利用したブレンディング画像と2つの画像を直接つなぎ合わせたものと比較する。
direct = np.hstack((src[:,:int(cols/2)],src2[:,int(cols/2):])) plt.figure(figsize=(10,8)) plt.subplot(1,2,1) plt.imshow(direct) plt.title('Direct Blending') plt.subplot(1,2,2) plt.imshow(ls_) plt.title('Pyramid Blending')
直接つなぎ合わせた場合と比較して、りんごとオレンジの輪郭、表面が自然につながっていることがわかるが、元の画像自体がつなぎ合わせる上で、画像の明るさやりんごとオレンジのサイズが合っているなど工夫が必要そうだ。
4. まとめ
今回は画像ピラミッドを応用した2つの画像のブレンディング処理について紹介した。