Python
matplotlib
python3

綺麗なお姉さんをMatplotlibで3D表示して遊んでみた

3Dの図って、なんだか見てて楽しいですよね〜
この図だってなんか、いい感じに勾配ができてます!

スクリーンショット 2017-10-19 23.09.39.png

画像を3D表示しよう

帰ってるときに画像を3Dで表示してみたら、なんかRGBの勾配とかわかって面白いんだろうなあとか思ってたのを思い出して、とりあえずやって見ました。
簡単のためにこんな感じで

  • 使う画像はモノクロ
    • R=G=Bになるので、これをCとでもすれば...
  • XZ平面上に画像の画素を配置して、Yの値をCにしてあげれば完成ですね

私はここ2ヶ月くらい機械学習の勉強をしたりしていたので、ローカルに保存されている写真といえばあれしかないと思って、Lenaさんを表示しました。Lenaさんといえば、実践 機械学習システムとかゼロから作るDeep Learningで目にしましたね!
この人です!

lena_gray.png

せっかくならこの綺麗なお姉さんを表示させよう!って感じです

正直、10行くらいのコードですが、最初何かわからないグラフが綺麗なお姉さんになるのは少し面白かったです

使ったもの

  • Python 3.6.2
  • matplotlib 2.0.2
  • numpy
  • (Axes3D)

matplotlibのscatter3Dを利用しました
scatter3Dは3次元データの散布図をプロットするための機能で、決してお姉さんを表示させるものではありません!

コード

やってること

  • 色々import
  • 画像のロード,XとZ軸のメモリ(?)の用意,y軸の値の用意
    • matplotlibの散布図の
image_3d.py
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.image import imread
from mpl_toolkits.mplot3d import Axes3D

x = z = np.linspace(-100, 100, 256)
x , z = np.meshgrid(x, z)
y = (255 - imread('./lena_gray.png')*255) * 10 #バラけさせたい

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter3D(np.ravel(x), np.ravel(z), np.ravel(y),s=10,marker='.')
ax.set_title("image")
plt.show()

実行結果

こんな感じです

実行結果

なんとも残念なことに、視点が決まってるんだからお姉さんの跡形もありませんね。

でもここからが1つすごいところなんですが
グラフ上をドラッグすることで、視点移動できるんですね!!

ちょっとドラッグしてお姉さんを頑張って呼び出して見ましょう!!

綺麗なお姉さんを探求して...

ドラッグしてみるとこんな感じになりました

スクリーンショット 2017-10-19 21.43.54.png

どうです...?なんか、見えてきましたよね!!
もっともっと回転させていきましょう!!

スクリーンショット 2017-10-19 21.44.11.png

だいぶ上から見てるのでのっぺりとしていますが、紛れもなくLenaさんですね!
画面に対して随分とグラフが小さいので、一工夫しましょう!

左下にあるこのメニューの右から二番目のスライダー的なアイコンをクリックしてください!

スクリーンショット 2017-10-19 21.45.33.png

そうすると次のようなウィンドウが表示されるので
グラフの左右上下の画面の端からの距離を移動させて、拡大させましょう!
感覚、CSSの設定みたいな感じですかね...

スクリーンショット 2017-10-19 21.45.27.png

こんな感じになりました!!
こんにちはLenaさん!!

スクリーンショット 2017-10-19 21.45.40.png

分かりにくいですが、写真立てみたいにするとこんな感じでした...

スクリーンショット 2017-10-19 22.10.40.png

まとめ

matplotlibすごいですね、Lenaさんを綺麗に表示していい感じに立体感を出してくれました
皆さんも、ちょっとずつドラッグして綺麗なお姉さんを表示させて見てはどうでしょうか...?

ついでに

色付けもして見ました

coloredImage_3d.py
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.image import imread
from mpl_toolkits.mplot3d import Axes3D

x = z = np.linspace(-100, 100, 256)
x , z = np.meshgrid(x, z)
img = imread('./lena_gray.png')
y = (255 - img*255) * 3

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter3D(np.ravel(x), np.ravel(z), np.ravel(y),marker='.',c=img)
ax.set_title("image")
plt.show()

スクリーンショット 2017-10-19 23.08.36.png

ax.scatter3D(np.ravel(x), np.ravel(z), np.ravel(y),marker='.',c=img,cmap="binary")

としてあげれば
スクリーンショット 2017-10-19 23.39.53.png

スクリーンショット 2017-10-19 23.42.27.png

こんな感じになります!