1.13. 簡単な画像処理¶
class, function, 属性など基本的なpythonの使い方を習得したので、これまでの復習を兼ねて簡単な画像処理をしてみよう。matplotlib
には画像データを読み込む関数image.imread
も用意されている。下記の画像はリンクフリーのサイトからダウンロードした。「白地図 japan05.jpg」で検索すると出てくる。
これをimage.imread
を使って、ndarray
の行列として読み出してみる。
from matplotlib import image
import matplotlib.pyplot as plt
import numpy as np
img = image.imread('japan05.jpg')
print(type(img))
print(img.shape)
print(img.dtype)
上に表示されているように、img
は縦横$1279\times 814$のサイズで、RGBの三つのフレーム(色の強度)からなる$3$次元のnp.ndarray
の形式になっている。要素は.dtype
というndarray
の属性で取得でき、uint8
つまりunsigned 8 bit int(符号なし8ビット整数型)であることが分かる。plt.imshow
を使って、$3$枚のフレームを表示してみる。
cmaps = ['Reds', 'Greens', 'Blues'] #listでcmapsを定義
plt.figure(figsize=(8, 4))
for n, cmap in enumerate(cmaps):
plt.subplot(1, 3, n+1)
plt.imshow(img[:,:,n], cmap=cmap)
#plt.tick_params(labelleft=False)
#plt.tick_params(labelbottom=False)
forループで紹介したenumerate
を使い、listの要素番号n
とそれに対応する要素cmap
を取得し、plt.subplot
とplt.imshow
内の変数として使っているところがポイントである。なお、plt.subplot
を使って横に3枚並べているが、左端のパネルを$0$番目ではなく$1$番目と数えるので、c
の部分は$4$行目のようにn
でなくn+1
としなければならないのはすでに紹介した通りである(ややこしい)。
このデータを使って陸地の部分の要素を$0$、海の部分の要素を$1$にもつ行列を作りたい。このうちのBlueのフレームを図示してみる。
plt.imshow(img[:,:,2], cmap='bone')
plt.colorbar();
のような感じなので、要素の値が$230$より小さい部分を陸地、それ以外を海とみなすことにする。(この$230$は目でみて適当に選んだ数字)
M = img[:,:,2] < 230
print(M.dtype)
if文のところで勉強したように、条件を満たす要素の抽出を行っているので、このM
はTrue
かFalse
を要素に持つ$1279 \times 814 $の行列である。True
/False
だと扱いにくいので、.astype
という属性を使って、True
を1
、False
を0
というunsigned 8 bit int(uint8
)に変換する。なおuint8
はNumPyの属性なので、.astype
の引数は、np.unit8
とする。
M = M.astype(np.uint8)
これでM
を$1279 \times 814$の0と1からなる行列として抽出できた。
plt.imshow(M, cmap='bone')
plt.colorbar();
このデータは偏微分方程式の数値計算のときに使うので、もう少し画像処理をしておく。$y=400$あたり(岩手県付近?)で横切ったときの値をプロットしてみると、
plt.plot(M[400, :])
print(M[400, 810:814])
のように、画像の枠の部分の2ピクセル分、つまりM[400,0:2]
, M[400,812:814]
が$1$になっていて、陸地とみなされてしまっている。これに注意しつつ、海の部分をもう少し広げて$2000 \times 1500$のサイズの行列にしておく。
map0 = np.zeros([2000, 1500])
a, b = M.shape
a0, b0 = 400, 300
map0[a0:a0+a-4, b0:b0+b-4] = M[2:a-2, 2:b-2]
plt.imshow(map0,cmap='bone');
これで2ピクセル分を枠を消して海の領域を広くした形で、日本地図を二値化した行列map0
を作ることができた。
データの保存¶
データはnp.save('ファイル名','配列名)
でndarry
の形式のまま保存できる。
np.save('map0', map0)
当サイトのテキスト・画像の無断転載・複製を固く禁じます。
Unauthorized copying and replication of the contents of this site, text and images are strictly prohibited.
© 2019 Go Yusa