ディープラーニングと物理学でPythonを勉強する①(画像処理)


1.はじめに

numpyを使って画像を処理する.

2.目次

1.はじめに
2.目次
3.とある思考実験
4.コード
5.まとめ
参考

2.とある思考実験

この本の中にとある思考実験が乗っている.その内容は妖精が目の前のボタンを一分ごとに押す/押さないを選択する事を繰り返し五日間,徹夜で作業させてその結果を行列で表現すると人の顔になっていると言うものである.この妖精は物理学で言うマクスウェルの悪魔である.

この労働は労働基準法に明らかに違反している.


第32条  
使用者は、労働者に、休憩時間を除き一週間について四十時間を超えて、労働させてはならない。
使用者は、一週間の各日については、労働者に、休憩時間を除き一日について八時間を超えて、労働させてはならない。


しかし,妖精に労働基準法が適用されるか不明なので気にしない事にする.今回,妖精が作り出した画像はlenna画像と呼ばれるサンプルデータである.今回はこちらのサイトのものを使用した.これを使って画像処理を行う.

4.コード

Pillow(PIL)とnumpyを用いて画像をnumpy配列にする.

from PIL import Image
import numpy as np


# PILでcat.jpgを開いてグレースケール画像に変換し、NumPy配列に変換
im = np.array(Image.open("画像のパス名").convert('L'))

# NumPy配列のshapeと、要素のデータ型を表示
print(im.shape, im.dtype)

# グレースケール化した画像のNumPy配列に変換したものを表示
print(im)

# 上記NumPy配列をテキストで保存
np.savetxt('im_lenna.txt', im)
(150, 150) uint8
[[164 163 161 ... 132 154 164]
 [160 160 159 ... 136 146 141]
 [157 157 156 ... 105  80  61]
 ...
 [ 54  55  54 ...  53  58  64]
 [ 51  49  50 ...  59  72  83]
 [ 49  48  52 ...  71  89 100]]

150×150=22500なので

im2 = im.reshape([1, 22500])#一次元配列に変更
np.savetxt('im_lenna.txt', im2)# 上記NumPy配列をテキストで保存
lenna = np.loadtxt('im_lenna.txt')# 上記で保存したNumPy配列を読み出す
print(lenna)
[164. 163. 161. ...  71.  89. 100.]

これを画像として出力する.

import matplotlib.pyplot as plt
%matplotlib inline
plt.imshow(lenna.reshape(150,150), cmap=plt.cm.gray_r)

また,これと比較するためにランダムに数字をふった画像を出力する.

まず,この画像は

print(lenna)
print(lenna.shape)
print(max(lenna))
[164. 163. 161. ...  71.  89. 100.]
(22500,)
236.0

を用いて,ランダムに値を代入する.


import random

random_lenna = [random.randint(0, 236) for i in range(len(lenna))]
random_lenna_n = np.array(random_lenna, dtype=float)

print(random_lenna_n)
[117.  92.   1. ...  88.  12.  55.]

これを画像として出力する.

plt.imshow(random_lenna_n.reshape(150,150), cmap=plt.cm.gray_r)

5.まとめ

本の中では妖精がボタンを押す/押さないの二つの値であったが,今回のコードは0から236までの値を入れる作業を行った事に対応する.妖精が適当に数字を選んでいくと2枚目の画像のような典型的状態になるはずだが,妖精(マクスウェルの悪魔)は2枚目のような例外的状態を作り出している.ご指摘,コメントなどをいただけたら幸いです.

参考

ディープラーニングと物理学 原理がわかる、応用ができる