大きくなったら大蛇に

Python始めたての初心者による学習ブログです

ステレオグラムの作り方_実践編1(菜の花畑)

ステレオグラムのデザインを考えよう

今日はステレオグラムのデザインをします。夢が広がる部分ですね。

まずは深度マップから。

深度マップの色の濃さによって3Dの浮き上がり度合いが変わると分かったときから、やってみたかったことがあります。

ステレオグラムをきれいな風景写真で作ってみたいのですが、浮き上がり度合いが変えられるのなら、風景を前景、中景、後景に分けて表現してみたいのです。前景は白にして一番大きく浮き上がらせて、中景はグレーに、後景は黒に近い灰色にして奥の方にという感じです。

背景には写真を使いますが、その写真にも遠近感をつけたいと思います。

こんな感じ↓



試行錯誤して、前景~空までのバランスを下のようにしました。あと、何も絵がないと寂しいので空に雲でも書いておきましょう。画像サイズは無難そうな1280×720にします。

では、上の深度マップに合わせる背景の写真を準備します。

以前スイカジュースの写真で試した時の感触から、背景写真の横のサイズは128ピクセルぐらいにとどめておいた方が良さそうです。

縦は深度マップのそれぞれ前景・中景・後景・空の高さと同じになるように作ります。

 

前景の画像

128(横)×64(縦)サイズ

中景の画像

128(横)×144(縦)サイズ



後景の画像

128(横)×92(縦)サイズ

 

空の画像

128(横)×420(縦)サイズ

 

これをPythonでくっつけます。

 

In[1] #インポートするライブラリ

import numpy as np
import cv2

In[2] #画像をくっつける

img1 = cv2.imread('画像のPath/ファイル名')
img2 = cv2.imread('画像のPath/ファイル名') 
img3 = cv2.imread('画像のPath/ファイル名') 
img4 = cv2.imread('画像のPath/ファイル名') 
img5 = cv2.imread('画像のPath/ファイル名')                                                                                                                                                                                        pattern_imshape=[1080,128,3]
pattern = np.zeros(pattern_imshape, dtype= img1.dtype)
pattern = cv2.vconcat([img1,img2,img3,img4,img5])
cv2.imwrite(’保存先のPath/ファイル名' , pattern)

できた画像がこちらです。↓

 

128(横)×720(縦)サイズ

 

これで深度マップも背景の元も完成しました。

これをステレオグラム化のアルゴリズムステレオグラムの作り方_応用編3から変更なし)に放り込んでみます!

 

ステレオグラム

In[1] #インポートするライブラリ

import numpy as np
import matplotlib.pyplot as plt
import cv2

In[2] #上で作った背景の元を読み込む

pattern = cv2.imread('画像のPath/ファイル名'')
pattern cv2.cvtColor(pattern, cv2.COLOR_BGR2RGB)

In[3] #上で作った深度マップを読み込む


img_depth  =
 cv2.imread('画像のPath/ファイル名')
img_depth  = cv2.cvtColor(depth_grad, cv2.COLOR_BGR2RGB)
 
def make_depthmap(shape=(720,1280,3)):
      black_img = np.zeros(shape, dtype=np.float64)
      depthmap = (black_img + img_depth)/255
      return depthmap                                                                                                                                                                                                                          depthmap = make_depthmap()

In[4] #ステレオグラムアルゴリズム適用 

def make_autostereogram(depthmap, pattern, shift_amplitude=0.1, invert=False):
     
    if invert: 
        depthmap = 1 - depthmap
    autostereogram np.zeros_like(depthmap, dtype=pattern.dtype)                                                                                                                                                        for color in np.arange(autostereogram.shape[2]):                                               
         for r in np.arange(autostereogram.shape[0]):
 
              for c in np.arange(autostereogram.shape[1]):
                if c < pattern.shape[1]:
                    autostereogram[r, c, color] = pattern[r % pattern.shape[0], c, color] 
                else
                    shift = int(depthmap[r, c, color] * shift_amplitude * pattern.shape[1])
                    autostereogram[r, c, color] = autostereogram[r, c - int(pattern.shape[1]) + shift, color]
 
    return autostereogram
 
autostereogram = make_autostereogram(depthmap, pattern, 0.3)
plt.imshow(autostereogram)

 

よーしよしよしできました!

いざ!チェック!

 

おお

おお?

おや?

前景・中景・後景の見え方は大体期待通りではあるけれど、、、

雲の右側になんかゴミが残ってますね。

 

あと、左端から横128ピクセルまでは立体になってませんね。左の雲が切れちゃってます。

横0~128ピクセル目までは背景の元のパターンをそのまま貼っているから、よく考えたらそりゃそうですが横0~128ピクセルまでの画像を参照して129ピクセル目以降を作っているのでこれはやむなしかな。。。

 

うーん。雲の右側のゴミ。

これは気持ち悪いなぁ。

 

次はこのゴミを消す方法を考えていきたいと思います。