Как отфильтровать цвет в OpenCV?

OpenCV (Open Source Computer Vision Library) — это библиотека программного обеспечения для машинного зрения и машинного обучения с открытым исходным кодом. Она имеет интерфейсы C++, Python, Java и MATLAB и поддерживает Windows, Linux, Mac OS, iOS и Android. OpenCV была разработана для вычислительной эффективности и с сильным акцентом на приложениях в реальном времени. Она используется для всех видов анализа изображений и видео, таких как распознавание и обнаружение лиц, чтение номерных знаков, редактирование фотографий, расширенное роботизированное зрение, оптическое распознавание символов и многое другое.

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

Цветовые пространства

Первый шаг — понять, как OpenCV представляет цветные изображения. OpenCV по умолчанию считывает изображения в массивы NumPy в формате BGR (Blue, Green, Red). Но OpenCV обеспечивает преобразование в другие цветовые пространства, такие как HSV и Lab, которые более интуитивно понятны для фильтрации на основе цвета.

Цветовое пространство BGR

Цветовое пространство BGR по умолчанию разделяет цветовые каналы на синий, зеленый и красный. Значения каналов находятся в диапазоне от 0 до 255. Фильтрация цвета напрямую в пространстве BGR затруднена, поскольку 3 канала коррелируют. Вместо этого нам нужно преобразовать в более интуитивно понятное цветовое пространство, такое как HSV или Lab.

Цветовое пространство HSV

Цветовое пространство HSV представляет цвет с использованием 3 значений — оттенка, насыщенности и значения. Это отделяет цвет (оттенок и насыщенность) от яркости (значения). Hue представляет собой доминирующий цвет, который находится в диапазоне от 0 до 179. Saturation описывает интенсивность цвета и находится в диапазоне от 0 до 255. Value работает как яркость изображения и находится в диапазоне от 0 до 255. HSV позволяет очень легко отфильтровывать цвета на основе Hue.

Цветовое пространство LAB

Цветовое пространство Lab использует 3 канала — Lightness, зелено-красную ось (a) и сине-желтую ось (b). Канал Lightness находится в диапазоне от 0 до 100. Канал a представляет собой диапазон от зеленого до красного с отрицательными значениями, указывающими на зеленый, и положительными значениями, указывающими на красный/пурпурный. Канал b представляет собой диапазон от синего до желтого с отрицательными значениями, указывающими на синий, и положительными значениями, указывающими на желтый. Lab позволяет легко пороговое значение цветов на основе каналов a и b.

Преобразование цветовых пространств

Поскольку HSV и Lab упрощают фильтрацию на основе цвета, нам необходимо преобразовать изображение OpenCV BGR в эти цветовые пространства. Это можно сделать с помощью функции cv2.cvtColor() в OpenCV.

Чтобы преобразовать из BGR в HSV:

import cv2 # Загрузка изображения BGR img = cv2.imread('image.jpg') # Преобразование в HSV hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) 

Чтобы преобразовать из BGR в Lab:

import cv2 # Загрузка изображения BGR img = cv2.imread('image.jpg') # Преобразование в Lab lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB) 

Это дает нам представления изображения в форматах HSV и Lab, которые лучше подходят для фильтрации на основе цвета.

Фильтрация в HSV

В HSV мы можем отфильтровать цветовой диапазон на основе диапазонов оттенка и насыщенности. Вот несколько примеров:

Фильтрация красного цвета

# нижняя и верхняя границы для красного цвета lower_red = np.array([0,50,50]) upper_red = np.array([10,255,255]) # Фильтрация красного цвета из изображения HSV mask = cv2.inRange(hsv, lower_red, upper_red) result = cv2.bitwise_and(img, img, mask=mask) 

Здесь мы определяем нижнюю и верхнюю границы HSV для красного цвета. Диапазон оттенка составляет 0-10 для красного цвета. Мы сохраняем полный диапазон насыщенности и значения. Мы применяем пороговую маску для фильтрации красных участков изображения.

Фильтрация зеленого цвета

# нижняя и верхняя границы для зеленого цвета lower_green = np.array([50, 50, 50]) upper_green = np.array([70, 255, 255]) # Фильтрация зеленого цвета из изображения HSV mask = cv2.inRange(hsv, lower_green, upper_green) result = cv2.bitwise_and(img, img, mask=mask) 

Для зеленого цвета диапазон оттенка составляет 50-70. На основе этого мы устанавливаем пороговое значение для изображения HSV, чтобы отфильтровать зеленый цвет.

Фильтрация синего цвета

# нижняя и верхняя границы для синего цвета lower_blue = np.array([100, 50, 50]) upper_blue = np.array([130, 255, 255]) # Фильтрация синего цвета из изображения HSV mask = cv2.inRange(hsv, lower_blue, upper_blue) result = cv2.bitwise_and(img, img, mask=mask) 

Здесь диапазон оттенков для синего составляет 100-130. Мы применяем пороговое значение для фильтрации синих областей.

Настраивая диапазоны оттенка и насыщенности, вы можете изолировать любой цвет из изображения HSV.

Фильтрация в Lab

В цветовом пространстве Lab мы можем установить пороговое значение на основе каналов a и b, чтобы изолировать цветовой диапазон. Вот несколько примеров:

Фильтрация красного цвета

# нижняя и верхняя границы для красного цвета lower_red = np.array([70, 50, 50]) upper_red = np.array([255, 255, 255]) # Фильтрация красных областей mask = cv2.inRange(lab, lower_red, upper_red) result = cv2.bitwise_and(img, img, mask=mask) 

Красный цвет имеет положительные значения канала a. Поэтому мы устанавливаем порог от 70 до 255, чтобы изолировать красные регионы.

Фильтрация синего цвета

# нижняя и верхняя границы для синего цвета lower_blue = np.array([0, 0, 50]) upper_blue = np.array([70, 255, 255]) # Фильтрация синих регионов mask = cv2.inRange(lab, lower_blue, upper_blue) result = cv2.bitwise_and(img, img, mask=mask) 

Синий цвет имеет отрицательные значения канала b. Поэтому мы устанавливаем порог от 0 до 70, чтобы изолировать синие регионы.

Фильтрация зеленого цвета

# нижняя и верхняя границы для зеленого цвета lower_green = np.array([0, 0, 50]) upper_green = np.array([255, 255, 255]) # Фильтрация зеленых регионов mask = cv2.inRange(lab, lower_green, upper_green) result = cv2.bitwise_and(img, img, mask=mask) 

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

Настраивая пороги каналов a и b, вы можете фильтровать любые цветовые диапазоны из изображения Lab.

Обнаружение контуров

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

Чтобы найти контуры на изображении маски, мы можем использовать функцию cv2.findContours():

import cv2 # получить изображение маски mask = cv2.inRange(hsv, lower_red, upper_red) # найти контуры contours = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contours = contours[0] if len(contours) == 2 else contours[1] # нарисовать контуры на изображении result = cv2.drawContours(img, contours, -1, (0,255,0), 3) 

Это находит контуры на изображении красной маски и рисует их на исходном изображении. Затем вы можете проанализировать эти контуры для обнаружения формы, отслеживания объектов и т. д.

Сегментация на основе цвета

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

Вот пример сегментации объектов синего цвета:

import cv2 import numpy as np # загрузка изображения img = cv2.imread('image.jpg') # преобразование BGR в Lab lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB) # пороговый синий цвет lower_blue = np.array([0, 0, 50]) upper_blue = np.array([70, 255, 255]) mask = cv2.inRange(lab, lower_blue, upper_blue) # поиск контуров contours = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contours = contours[0] if len(contours) == 2 else contours[1] # инициализация выходного изображения output = np.zeros(img.shape, dtype='uint8') # рисование синих контуров на выходе cv2.drawContours(output, contours, -1, (255, 0, 0), 3) # показ выходных данных cv2.imshow('Output', output) cv2.waitKey(0) 

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

Отслеживание цветного объекта

Вы можете использовать цветовую фильтрацию для отслеживания объектов определенного цвета на видео. Чтобы отслеживать синий объект:

import cv2 import numpy as np # захват видео cap = cv2.VideoCapture('video.mp4') while True: # чтение каждого кадра ret, frame = cap.read() # преобразование в LAB lab = cv2.cvtColor(frame, cv2.COLOR_BGR2LAB) # пороговый синий lower_blue = np.array([0,0,50]) upper_blue = np.array([70,255,255]) mask = cv2.inRange(lab, lower_blue, upper_blue) # поиск и рисование контуров contours = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contours = contours[0] if len(conours) == 2 else contours[1] cv2.drawContours(frame, contours, -1, (0,0,255), 2) cv2.imshow('Tracking', frame) if cv2.waitKey(1) == ord('q'): break cap.release() cv2.destroyAllWindows() 

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

Заключение

Подводя итог, вот основные шаги для фильтрации цвета в OpenCV:

  1. Загрузка изображения как BGR
  2. Преобразование в цветовое пространство HSV или Lab
  3. Определение нижней и верхней пороговых границ для цвета
  4. Пороговое изображение HSV или Lab
  5. Применение побитового И к маске для извлечения цвета
  6. (Необязательно) Поиск контуров в Маска для изоляции объектов

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

OpenCV предоставляет все необходимые строительные блоки для эффективной фильтрации и обнаружения цветов в изображениях и видео. Благодаря обширной библиотеке и простому интерфейсу Python реализация отслеживания и аналитики на основе цвета в реальном времени становится очень простой.