Статья Автор: Деникина Наталья Владимировна

Сравнение цвета с эталоном

Сравнение цвета с эталоном

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

Один из эффективных методов для выполнения такой проверки – использование среднего цвета и погрешности. В данном разделе мы рассмотрим теоретическую основу и практическую реализацию метода для сравнения цвета с эталоном.

Метод сравнения цвета с эталоном основывается на следующих шагах:

  1. Вычисление среднего цвета части изображения:

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

    • Проверка заключается в определении, находится ли средний цвет в пределах допустимой погрешности относительно эталонного цвета. Это достигается путем вычитания эталонного цвета из среднего цвета и проверки, не превышает ли абсолютное значение разницы заданную погрешность для каждого цветового канала.

Ниже представлена функция check_color, которая выполняет указанные шаги и возвращает результат проверки.

def check_color(img, color, tolerance=30):
    avg_color = np.mean(img, axis=(0, 1))  # Вычисление среднего цвета части изображения
    return np.all(np.abs(avg_color - color) < tolerance)  # Сравнение с эталонным цветом

Вычисление среднего цвета

Функция check_color рассчитывает средний цвет части изображения, используя метод np.mean(). Понимание того, как работает этот метод, и примеры его применения помогут лучше понять процесс и адаптировать его для других задач.

np.mean()

Функция np.mean() из библиотеки NumPy вычисляет среднее значение элементов массива. Она принимает два основных параметра:

  • axis — ось или оси, вдоль которых нужно вычислить среднее.
  • dtype — тип данных, в который нужно преобразовать результат.

При применении к изображению, которое представлено как многомерный массив (ширина x высота x каналы), np.mean() может быть использована для вычисления среднего значения вдоль различных осей.

Примеры нахождения среднего по разным осям

1. Среднее значение всех пикселей изображения:


Можно ли с уверенностью сказать, что это изображение серое? Не совсем, т.к. может быть и так:


Среднее значение очень близко, однако изображение, очевидно, синее!


2. Среднее значение по каждому каналу (B, G, R):
Решением может стать вычисление среднего значения по каждому каналу. Для этого необходимо указать оси массива, по которым будет производиться вычисления среднего: axis=(0, 1). Т.е. по ширине и высоте, в результате получим массив из трех значений - среднее по каждому каналу!


Теперь видна разница, и можно определить цвет точнее

 

Сравнение среднего цвета с эталонным

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

np.all(np.abs(avg_color - color) < tolerance)

Разберем ее по частям.

avg_color - color

Здесь происходит вычитание эталонного цвета color из среднего цвета avg_color. Поскольку и avg_color, и color являются массивами, содержащими значения для каждого из цветовых каналов (B, G, R), результатом будет массив разностей для каждого канала:

np.abs(avg_color - color)

Функция np.abs() вычисляет абсолютное значение элементов массива (значение "по модулю"). 

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

abs_diff < tolerance

Это условие сравнивает каждое значение в массиве абсолютных разностей с заданной погрешностью tolerance. В результате получается массив булевых значений, где каждое значение указывает, удовлетворяет ли соответствующий канал условию:

np.all()

Функция np.all() проверяет, являются ли все значения в булевом массиве True. Если хотя бы одно значение Falsenp.all() вернет False

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

 

Пример


В этом примере все компоненты среднего цвета отличаются от соответствующих компонентов эталонного цвета на значения, меньшие допустимой погрешности (10). Поэтому функция возвращает True, указывая на то, что средний цвет совпадает с эталонным в пределах заданной погрешности.
 

Сравнение цвета с ближайшим эталоном

Помимо проверки совпадения цвета с заданным эталоном в пределах допустимой погрешности, иногда возникает необходимость найти ближайший к данному цвет. Это может быть полезно, когда точного совпадения нет, но требуется определить, какой из известных цветов наиболее похож на данный. Для выполнения этой задачи можно использовать метод нахождения ближайшего цвета.

Метод нахождения ближайшего цвета основывается на вычислении расстояния между цветами в цветовом пространстве. Наиболее часто используемым расстоянием является евклидово расстояние. Этот метод включает следующие шаги:

  1. Вычисление расстояния между цветами:

    • Расстояние между двумя цветами (каждый из которых представлен в виде вектора значений цветовых каналов) рассчитывается как евклидово расстояние между этими векторами. Евклидово расстояние можно интерпретировать как длину отрезка, соединяющего две точки в многомерном пространстве.
  2. Поиск минимального расстояния:

    • Сравниваются расстояния между данным цветом и всеми цветами из набора эталонных цветов. Находится цвет, расстояние до которого минимально, и он считается ближайшим.

 

Как вычислить расстояние?

distance = np.linalg.norm(np.array(color) - np.array(key))

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

  1. np.array(color) и np.array(key):

    • Преобразуем входные параметры color и key (кортежи или списки) в массивы NumPy. Это необходимо для того, чтобы можно было выполнять математические операции над ними, такие как вычитание.
  2. np.array(color) - np.array(key):

    • Выполняем вычитание одного массива из другого. В результате получается массив разностей для каждого канала (B, G, R). Если color = [100, 150, 200] и key = (255, 0, 0),
      то результат вычитания будет будет равен [-155, 150, 200]
  3. np.linalg.norm(...):

    В нашем случае, мы вычисляем евклидово расстояние между двумя цветами. Для примера с [-155, 150, 200]
    # distance будет равен sqrt((-155)^2 + 150^2 + 200^2) # что приблизительно равно 294.14

    • Функция np.linalg.norm() из библиотеки NumPy вычисляет норму (длину) вектора. По умолчанию, если не указать дополнительные параметры, она вычисляет евклидову норму (или длину) вектора. Евклидова длина вектора xxx с компонентами \((x_1, x_2, ..., x_n)(x_1, x_2, ..., x_n)...(x_1, x_2, ..., x_n)\) вычисляется как:
\(|x|=\sqrt{x_1^2+x_2^2+...+x_n^2}\)

Таким образом, строка distance = np.linalg.norm(np.array(color) - np.array(key)) вычисляет евклидово расстояние между двумя цветами, представленными в виде массивов, что позволяет определить, насколько эти цвета близки друг к другу в цветовом пространстве.

Пропустить Навигационные Ссылки.
Чтобы оставить комментарий нужна авторизация
Печать