>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> import scipy as sp
1.5.11.4. 图像处理练习的解决方案示例:玻璃中的未熔颗粒¶
打开图像文件 MV_HFV_012.jpg 并显示它。浏览
imshow
文档字符串中的关键字参数,以“正确”的方向显示图像(原点在左下角,而不是像标准数组那样在左上角)。>>> dat = plt.imread('data/MV_HFV_012.jpg')
裁剪图像以去除带有测量信息的底部面板。
>>> dat = dat[:-60]
使用中值滤波器稍微滤波图像,以细化其直方图。检查直方图如何变化。
>>> filtdat = sp.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
显示一个图像,其中三个相位用三种不同的颜色着色。
>>> phases = void.astype(int) + 2*glass.astype(int) + 3*sand.astype(int)
使用数学形态学来清理不同的相位。
>>> sand_op = sp.ndimage.binary_opening(sand, iterations=2)
为所有气泡和沙粒分配标签,并从沙子掩码中去除小于 10 个像素的颗粒。为此,使用
sp.ndimage.sum
或np.bincount
计算颗粒尺寸。>>> sand_labels, sand_nb = sp.ndimage.label(sand_op) >>> sand_areas = np.array(sp.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 = sp.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 (np.float64(1699.875), np.float64(65.0))