图像处理
Python 提供了几个很棒的库,可以对图像进行广泛的操作。更多信息,请阅读以下教程: * OpenCV * Scikit Image
在本实例中,我们只介绍了玩骰子时的一些经典图像处理操作。这个例子的目标是计算一个骰子的总分,答案是113113.
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from scipy import ndimage
import pandas as pd
import os
%matplotlib nbagg
图片 dices.tif。
我们将图片放置在程序目录下
首先,让我们检查文件dices.tif是否在当前目录中。
path = "dices.tif"
files = os.listdir("./")
if path in files:
print("Ok, the file is in {0}".format(files))
else:
print("The file is not in {0} , retry !".format(files))
现在让我们使用Python 图像库(又名 PIL)来读取图片:
im = Image.open(path)
Nc, Nl = im.size
im = im.resize((Nc // 2 ,Nl // 2),Image.ANTIALIAS)
fig, ax = plt.subplots()
ax.axis("off")
plt.imshow(im)
plt.show()
转换灰度
R, G, B = im.split()
R = np.array(R)
G = np.array(G)
B = np.array(B)
R
array([[223, 221, 224, ..., 195, 195, 193],
[225, 225, 221, ..., 194, 195, 194],
[223, 223, 223, ..., 195, 195, 195],
...,
[229, 228, 231, ..., 192, 195, 196],
[230, 229, 229, ..., 192, 194, 195],
[230, 229, 228, ..., 193, 195, 196]], dtype=uint8)
fig = plt.figure()
ax1 = fig.add_subplot(3, 1, 1)
plt.title("R")
plt.imshow(R, cmap = cm.gray)
ax1.axis("off")
ax1 = fig.add_subplot(3, 1, 2)
plt.title("G")
plt.imshow(G, cmap = cm.gray)
ax1.axis("off")
ax1 = fig.add_subplot(3, 1, 3)
plt.title("B")
plt.imshow(B, cmap = cm.gray)
ax1.axis("off")
plt.show()
绿色通道有很好的对比,所以我们现在选择只在这个通道上工作。
直方图
直方图显示了像素在色标上的重新划分。
plt.figure()
plt.hist(G.flatten(), bins = np.arange(256), histtype = "stepfilled")
plt.grid()
plt.xlabel("Pixel value")
plt.ylabel("Pixel count")
plt.show()
阈值
使用直方图,可以看到有 3 个峰值。左峰是最暗的峰,对应于骰子体的颜色。我们可以绕过120 将骰子体与骰子上的点分开。
进一步阅读:阈值(Scikit)
Gt = G < 120 # Thresholding
plt.figure()
plt.imshow(Gt, cmap = cm.gray, interpolation = "nearest")
plt.grid()
#plt.colorbar()
plt.show()
侵蚀
struc = np.ones((8,8))
Gtd = ndimage.binary_dilation(Gt, structure = struc)
Gtde = ndimage.binary_erosion(Gtd, structure = struc)
plt.figure()
plt.imshow(Gtde, cmap = cm.gray, interpolation = "nearest")
plt.grid()
plt.show()
标签
Gtdel, number = ndimage.measurements.label(Gtde == False)
number
114
plt.figure()
plt.imshow(Gtde,cmap = cm.gray, interpolation = "nearest")
plt.imshow(np.where(Gtdel > 1, Gtdel, np.nan),
cmap = cm.jet, interpolation = "nearest")
plt.grid()
plt.show()
data = Gtdel.flatten()
count = np.bincount(data)
(count < 1000).sum()
113
所以总分是 113,方法有效!