Определите круги определенных цветов, используя opencv - PullRequest
2 голосов
/ 03 июля 2019

Мне нужно обнаружить желтые круги на изображении, используя OpenCV и python, как показано на первом изображении:

Picture 1 image

Как только я обнаружу желтый круг, я должен выделить его, например, так:

Picture 2

Я новичок в OpenCV, поэтому я искал какое-то руководство или помощь. Вся помощь приветствуется

1 Ответ

3 голосов
/ 03 июля 2019

Вот потенциальный подход:

  • Преобразование изображения в HSV
  • Поиск верхних / нижних цветовых границ и создание маски
  • Поиск контуров и фильтра по номерувершин

Мы конвертируем изображение в HSV, а затем определяем нижнюю и верхнюю границы для создания маски, используя cv2.inRange().Этот шаг изолирует желтые объекты

image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([0, 208, 94], dtype="uint8")
upper = np.array([179, 255, 232], dtype="uint8")
mask = cv2.inRange(image, lower, upper)

image

Далее, чтобы определить форму, мы находим контуры и фильтруем, используя количество вершин.Мы используем cv2.arcLength() и cv2.approxPolyDP(), чтобы получить список вершин и приблизительных контуров.Мы можем проверить количество записей в этом списке, чтобы определить форму объекта.Например, если контур имеет три вершины, он должен быть треугольником.Точно так же, если у этого есть четыре вершины, это должен быть квадрат.Таким образом, для этого изображения мы можем сделать предположение, что форма является кругом, если у нее больше определенного числа вершин.Вот результат

image

import numpy as np
import cv2

image = cv2.imread('1.png')
original = image.copy()
image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([0, 208, 94], dtype="uint8")
upper = np.array([179, 255, 232], dtype="uint8")
mask = cv2.inRange(image, lower, upper)

# Find contours
cnts = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Extract contours depending on OpenCV version
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

# Iterate through contours and filter by the number of vertices 
for c in cnts:
    perimeter = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.04 * perimeter, True)
    if len(approx) > 5:
        cv2.drawContours(original, [c], -1, (36, 255, 12), -1)

cv2.imshow('mask', mask)
cv2.imshow('original', original)
cv2.imwrite('mask.png', mask)
cv2.imwrite('original.png', original)
cv2.waitKey()
...