大きくなったら大蛇に

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

ステレオグラムの作り方_応用編3(カラー化)

■好きな画像でステレオグラムを作りたい

今回はいよいよカラー化をします。

ステレオグラムが作れることが分かると、次は綺麗なステレオグラムを見たくなってきてしまいました。

綺麗なステレオグラムを作るのにあたってカラー化は必須!

しっかり考えていきましょう。

 

背景は「ステレオグラムの作り方_応用編1」で使ったスイカジュースの画像を使います。

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)
plt.imshow(pattern)

表示は無事にカラー化できました。

cv2で画像を読み込んでいるので色の並びがBGRになっています。cv2.cvtColorで画像データの並びをBGRからRGBに変換します。

plt.imshowのカラーマップは何を選んで良いか分からなかったので何も記載しませんでしたが、いい感じにカラー化してくれました。ありがとう。

 

次に深度マップですがこちらも「ステレオグラムの作り方_応用編2」で使った深度マップを使い回します。

In[3] #深度マップを作成

depth_grad = cv2.imread('画像のPath/ファイル名.png')
depth_grad = cv2.cvtColor(depth_grad, cv2.COLOR_BGR2RGB)
 
def make_depthmap(shape=(400,600,3)):
      black_img = np.zeros(shape, dtype=np.float64)
      depthmap = (black_img + depth_grad)/255
      return depthmap 
 
depthmap = make_depthmap() 
plt.imshow(depthmap, cmap="gray")

使い回しはしますが、shapeの型だけは背景画像のカラーと揃えておきます。

グレースケールの時はshapeが(400,600)でしたが、背景がカラーになったので

背景画像と同じカラーの型でshapeが(400,600,3)となるようにしておきます。

詳細は下のIn[5]にて。

 

In[4] #基本編1からずっとやってきた正規化は削除です。

def normalize(depthmap):
        return depthmap/255

カラー化したらdepthmapの最大値が255じゃなくなったようで、255のままだとエラーが出るようになりました。そもそも正規化する意味が見つけられなかったので、必要性が理解できるときまで、削除しておきます。

 

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

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] = pattern[r pattern.shape[0], c]
                   else:
                       shift = int(depthmap[r, c] * shift_amplitude * pattern.shape[1])
                       autostereogram[r, c] = autostereogram[r, c pattern.shape[1+ shift]
 
    return autostereogram
 
autostereogram = make_autostereogram(depthmap, pattern, 0.3)
plt.imshow(autostereogram)

さて、問題はIn[5]ですね。

ステレオグラム化のアルゴリズムでは、背景の元になるスイカジュースの画像を台紙(深度マップと同じサイズの台紙)に並べてペタペタ貼っていくことをしています。

 

いままではグレースケール画像だったのでモノクロ用の台紙1枚だけに「台紙(深度マップ画像と同じサイズ)いっぱいになるまで背景画像を貼り続ける」ということを"for ** in "で実行すればよかったのですが、ここにカラーという要素が加わります。

カラーになると背景画像を張り付ける台紙が赤・緑・青の3枚に増えます。(下図のイメージ)

なので、 「深度マップ画像の縦サイズと横サイズいっぱいになるまで貼り続ける」ということを3回繰り返さないといけないです。

 

   グレースケールの時         カラーの時

 

"for ** in range(3)"

と書いても動くと思いますが、格好をつけたいのでautostereogram.shapeの値を使いたいと思います。

"autostereogram.shape"と打つと(400,600,3)と出ます。 3番目の3が赤・緑・青の台紙の3色を表現してくれるので、これを

 for color in np.arange(autostereogram.shape[2]):

という形で使います。

 

結果がこちら↓

 

 おおおお!いい感じではないですか。

すごいすごい!

 

では、次回はちょっとヒネリを入れったデザインでステレオグラムを作っていきます!