Работа с цветными файлами или файлами изображений может быть сложной. Терминология очень специфична для этой области, и объяснения всего процесса встречаются редко.

Что такое цветовая маска?

Как использовать альфа-канал?

Где граница фона?

Разъедать, расширять… ты с ума сошел?

Моя цель состояла в том, чтобы создать продукт, который находит доминирующий цвет объекта. Я определяю доминирующий цвет как цвет самых больших непрерывных областей пикселей одного цвета. Давайте рассмотрим шаги, необходимые для обработки цвета изображения и определения доминирующего цвета. Тогда в качестве бонуса мы рассмотрим эффективную стратегию маркировки обнаруженного цвета!

У нас есть 3 основных шага для обнаружения: предварительная обработка изображения, удаление фона и группировка пикселей по цвету. Маркировка включает в себя определение имен для разных типов цветов и выбор наиболее похожего на обнаруженный цвет. Я следую этим шагам в остальной части статьи, чтобы объяснить их последовательно, чтобы упростить репликацию.

Предварительная обработка изображений

Думайте об этом как об очистке изображения и преобразовании его в формат, с которым может работать компьютер. В этом случае нам нужно импортировать изображение в виде большого массива цветов RGB (красный, зеленый, синий).

Каждый пиксель цвета будет представлен своей пропорцией красного, зеленого и синего цветов в виде кортежа. Например: белый - это (255, 255, 255), поэтому максимальное количество всех трех цветов вместе. А синий может быть (0,0, 255), так что ни красного, ни зеленого, а много синего! Возьмите этот массив цветов RGB и добавьте к нему альфа-канал (каждый цвет или атрибут, из которого состоит цвет, называется каналом), чтобы получить RGBA (см. https://en.wikipedia.org/wiki/RGBA_color_space для получения дополнительной информации). ). A или альфа — это канал прозрачности, поэтому что-то с альфой 0 будет четким/видимым. Это будет полезно, когда мы запустим удаление фона, потому что мы можем маскировать (маскировать — значит помечать определенные пиксели на изображении для удаления) области изображения, которые кажутся фоном, и вместо того, чтобы просто окрашивать этот фон в черный цвет. или белый, мы можем замаскировать все цвета с помощью альфа-канала.

Удаление фона

Наиболее важным этапом обработки для повышения точности определения цвета является удаление фона. Второстепенная проблема заключается в том, что фон представляет собой большую область одного цвета, чем сам объект! Мы должны хорошо замаскировать фон, чтобы иметь возможность получить точное совпадение цветов.

Я получил приличное обнаружение фона и удаление внешних краев изображения, запустив алгоритм обнаружения краев, называемый canny, чтобы идентифицировать центральный объект на изображении и пометить все участки изображения с похожим цветом за его пределами как фон.

Этот алгоритм не может обрабатывать пограничный случай, когда объект имеет области фона внутри границ объекта.

Поэтому добавьте метод удаления фона 2: заливка заливкой! Основная концепция этого забавна, представьте, что вы заливаете краску, начиная с краев изображения, и краска может покрывать только цвета, похожие на цвет края, с которого она началась. Вы можете думать об этом, если хотите, как о нескольких методах, потому что вы запускаете алгоритм несколько раз, по одному разу из каждого угла, пока не получите желаемое фоновое покрытие. Это отлично подходит для заполнения тех раздражающих контуров, которые пропустил первый детектор.

Группировка цветов пикселей

Двигаясь плавно, теперь у нас есть изображение с удаленным фоном, которое нам нужно для определения доминирующего цвета! Для этого мы полагаемся на традиционную технику объединения пикселей. Думайте об этом как об оценке цвета пикселя со всеми окружающими его пикселями, чтобы вырастить области схожего цвета, как метод машинного зрения, называемый расширением. Как только все цветовые области расширены/объединены в максимально возможной степени, подсчитывается количество пикселей в каждой области, и этот цвет выбирается в качестве доминирующего цвета.

Ну вот, это изображение называлось (49,77,153).

Именование цветов

Теперь у нас есть доминирующий цвет, но это раскрывает интересную дилемму. Какое название вы бы дали этому цвету? В этом случае наше изображение явно находится в семействе цветов для (49,77,153). Это синий или средний синий или даже определенный оттенок синего? Нам нужно вернуть только одно имя цвета из непрерывного цветового пространства (попробуйте изобразить цветовое пространство как все возможные цвета, чтобы на самом деле было (0–256) x (0–256) X (0–256) = 16 777 216 различных цветов в стандартном цветовом пространстве RGB. ). Для бизнес-приложения, над которым я работал, мне нужно было только ограниченное количество названий цветов (40) и выбрать только имя цвета, наиболее похожего на выбранный доминирующий цвет.

Быстрая мысль: при определении цвета мы можем быть обмануты тенями. Скажем, у вас есть средний синий цвет в тени. Вы хотите, чтобы детектор сказал, что это оттенок синего, а не серый! Это называется быть независимым от тени/освещения. Для этого я оценил доминирующий цвет в цветовом пространстве HSI (https://en.wikipedia.org/wiki/HSL_and_HSV). Это позволяет мне представлять легкость как I (интенсивность) и позволяет мне выбирать похожий цвет на основе первых двух: оттенка и насыщенности, которые распределяются вокруг центральной оси этого цветового спектра. Если копнуть немного глубже, это означает, что черный будет находиться в основании перевернутой пирамиды и иметь радиус, близкий к 0, и интенсивность, близкую к 0. Белый будет по-прежнему иметь радиус, близкий к 0, но с максимальной интенсивностью 100%. Это использование оттенка, насыщенности и интенсивности пытается создать более интуитивное представление цвета, имитируя то, как глаз воспринимает цвет.

Самый похожий цвет

Чего я очень хочу, так это максимально похожего цвета! Это должно звучать так же, как проблема ближайшего соседа (см. https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm для общего случая): какой цвет ближе всего в цветовом пространстве к входу. Чтобы решить эту проблему, мы можем реализовать нашу собственную ручную версию алгоритма ближайшего соседа, чтобы создать функцию расстояния на основе полярной геометрии цветового пространства. Вы можете проследить в приведенном ниже фрагменте кода, что мы масштабируем геометрическое расстояние по полярным координатам между доминирующим цветом и каждым цветом в наших именованных цветах. Это означает расстояние в градусах оттенка, радиальное расстояние насыщенности и вертикальное расстояние интенсивности. Таким образом, примерно в 9 строках кода у нас есть надежная метрика расстояния, чтобы вернуть идентификатор наиболее похожего цвета!

Для кожаной куртки в приведенном выше примере сопоставленным цветом был королевский синий.

Заключение и комментарии

Надеюсь, что это было хорошим резюме для вас, чтобы получить терминологию и методы, необходимые для воспроизведения этого решения распространенной проблемы, какого цвета мое изображение. Этот алгоритм был специально разработан для обработки любых входных изображений, поскольку входными данными, для которых он был построен, может быть любой тип объекта. Не ожидайте, что он будет стабильно хорошо работать с объектом на фоне фона сцены. Я думаю, это интуитивно понятно: слишком много больших областей фона, чтобы запутать детектор. Я также удалился из проекта и не стал обсуждать какие-либо причудливые методы ограничивающей рамки или сегментацию изображения нейронной сети, поскольку они не поддерживают обобщенный вариант использования детектора цвета для любого типа объекта. Вы можете во что бы то ни стало добавить их, чтобы заменить удаление фона, если у вас есть чисто ограниченная задача, просто имейте в виду, что они требуют много обучающих данных и не будут такими быстрыми, как этот метод. Удачи вам в применении этой технологии и не стесняйтесь обращаться к моему репозиторию за демонстрационной версией кода, который я создал. Он не оптимизирован и намеренно делает только одно изображение за раз. Это упрощает наблюдение за ходом алгоритма и позволяет пользователю сохранять промежуточные изображения, чтобы увидеть, насколько хорошо работает каждый шаг.