Menu
CoddyTech

Цвета изображений

Часть раздела Обучение без учителя путешествия по Machine Learning на Coddy. Урок 41 из 51.

У трафаретного печатника есть несколько красок, а не миллионы цветов. k-means выбирает несколько лучших для любой картинки:

Два изображения заката рядом. Слева — оригинал: небо, переходящее от фиолетового к оранжевому, жёлтое солнце, тёмное море с оранжевым отражением. Справа — тот же закат в 4 плоских цветах

Цветное изображение имеет форму (строки, столбцы, 3): красный, зелёный и синий для каждого пикселя, каждый в диапазоне от 0 до 1. Одно изменение формы превращает пиксели в данные:

Изображение размером 2 на 3 пикселя: оранжевые, жёлтые и тёмно-синие пиксели; стрелка указывает на таблицу из 6 строк, по одной на пиксель, в каждой указаны значения красного, зелёного и синего

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 складывает строки обратно в изображение.

challenge icon

Задание

Средне

Студия постеров печатает на горном озере изображение с помощью k красок. Стартовый код рисует изображение размером 40 на 60 image, считывает k и создаёт график с заголовком.

  1. Преобразуй изображение в строки, по одной на каждый пиксель, и найди k цветов с помощью метода k-средних.
  2. Перекрась каждый пиксель в цвет его центра и снова собери строки в изображение.
  3. Нарисуй его на ax и покажи.

Например, этот закат использует 5 красок:

Закат, перекрашенный в 5 ровных цветов, с заголовком «5 красок»: сливовая и розовая полосы неба, оранжевая полоса, жёлтое солнце, тёмно-синее море с оранжевыми полосами

Твоя программа ничего не выводит: Coddy описывает твоё изображение и использованные краски. Затем попробуй другие значения 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")

# Напишите свой код ниже
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Обучение без учителя

Потренируйтесь самостоятельно: Онлайн-компилятор Python