>>> import numpy as np
>>> import pylab as pl
>>> from scipy import ndimage
1.5.11.4. 画像処理練習問題解答例: ガラスの中の非融解粒¶
MV_HFV_012.jpg を開いて表示しましょう.
imshow
のドキュメンテーション文字列を眺めて右方向 “right” orientation (原点が左下の角になり、普通の配列のように左上の角にない)状態で開きましょう:>>> dat = pl.imread('data/MV_HFV_012.jpg')
測定情報を表示している下のパネル部分を切り取りましょう.
>>> dat = dat[:-60]
頻度分布を明確にするために少しだけ中央値フィルターをかけましょう. 頻度分布がどう変化したか調べましょう.
>>> filtdat = ndimage.median_filter(dat, size=(7,7)) >>> hi_dat = np.histogram(dat, bins=np.arange(256)) >>> hi_filtdat = np.histogram(filtdat, bins=np.arange(256))
フィルタした画像の頻度分布を使って, 砂, ガラス, 泡のピクセルのマスクを定義するための閾値を決定しなさい. オプション(宿題): 頻度分布の最小値から閾値を自動的に決定する関数を書きなさい.
>>> void = filtdat <= 50 >>> sand = np.logical_and(filtdat > 50, filtdat <= 114) >>> glass = filtdat > 114
3つの相を異なる色で表示しなさい.
>>> phases = void.astype(np.int) + 2*glass.astype(np.int) + 3*sand.astype(np.int)
異なる相のごみをとるために数理形態学を使いなさい.
>>> sand_op = ndimage.binary_opening(sand, iterations=2)
全ての泡と砂粒にラベルをつけ, そして10ピクセルより小さい砂粒のマスクを取り除きなさい. そうしたら,
ndimage.sum
かnp.bincount
を使って粒の大きさを計算しなさい.>>> sand_labels, sand_nb = ndimage.label(sand_op) >>> sand_areas = np.array(ndimage.sum(sand_op, sand_labels, np.arange(sand_labels.max()+1))) >>> mask = sand_areas > 100 >>> remove_small_sand = mask[sand_labels.ravel()].reshape(sand_labels.shape)
泡の平均的大きさを計算しなさい.
>>> bubbles_labels, bubbles_nb = ndimage.label(void) >>> bubbles_areas = np.bincount(bubbles_labels.ravel())[1:] >>> mean_bubble_size = bubbles_areas.mean() >>> median_bubble_size = np.median(bubbles_areas) >>> mean_bubble_size, median_bubble_size (1699.875, 65.0)