图像颜色
本课属于 Coddy Machine Learning 学习旅程的“无监督学习”单元。第 41 课,共 51 课。
丝网印刷工只有几种油墨,没有数百万种颜色。k-means 会为任意图片挑选最合适的几种颜色:
彩色图像的形状为 (rows, columns, 3):每个像素包含红、绿、蓝三个通道,每个通道的值都在 0 到 1 之间。通过一次 reshape,就可以将像素转换为数据:
pixels = image.reshape(-1, 3)
km = KMeans(n_clusters=4, n_init=10, random_state=0).fit(pixels)
poster = km.cluster_centers_[km.labels_].reshape(image.shape)
ax.imshow(poster)每个中心都对应一种颜色。用标签对中心进行索引,就能为每个像素赋予其中心的颜色;reshape 会将各行折叠回一张图片。
挑战
中等一家海报工作室用 k 种油墨丝网印刷一幅山间湖泊图。起始代码绘制了 40 × 60 的 image,读取 k,并设置好带标题的图表。
- 将图像转换为每个像素占一行的形式,并用 k-means 找出
k种颜色。 - 用中心颜色重新绘制每个像素,再将各行折回成一幅图。
- 在
ax上绘制图像并显示出来。
例如,这幅用 5 种油墨绘制的日落图:
你的程序不会打印任何内容:Coddy 会描述你的图像和所用的油墨。然后试试其他 k 值:k 取多少时,红色小船会拥有自己的油墨颜色?
亲手试试
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
# 绘制一幅 40 × 60 的山间湖泊图:画面中有天空、雪峰、森林、湖水和一艘红船
def paint_lake():
image = np.zeros((40, 60, 3))
for r in range(40):
for c in range(60):
if 30 <= r <= 31 and 10 <= c <= 17 - (r - 30) * 2:
image[r, c] = [0.8, 0.15, 0.1]
elif r >= 27:
t = (r - 27) / 12
image[r, c] = [0.1, 0.45 - 0.2 * t, 0.65 - 0.2 * t]
elif r >= 21:
image[r, c] = [0.1, 0.35 + 0.05 * (c % 3), 0.15]
elif r >= abs(c - 34) + 4 and r < 10:
image[r, c] = [0.95, 0.95, 0.97]
elif r >= abs(c - 34) + 4:
image[r, c] = [0.45, 0.42, 0.45]
else:
image[r, c] = [0.55 + r / 50, 0.75 + r / 120, 0.95]
return np.round(image, 3)
# 不要修改下面的代码
image = paint_lake()
k = int(input())
fig, ax = plt.subplots()
ax.set_title(f"{k} inks")
ax.axis("off")
# 在下方编写你的代码
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
无监督学习中的所有课
自己练习: Python 在线编译器