Мне удалось найти доминирующий цвет для каждого круга, выполнив следующие шаги:
Сначала я обнаружил круги с cv2.HoughCircles
:
def detectCirclesWithDp(frame, dp=1):
blurred = cv2.medianBlur(frame, 25)
grayMask = cv2.cvtColor(blurred, cv2.COLOR_BGR2GRAY)
# cannyMask = cv2.Canny(grayMask, 50, 240)
return cv2.HoughCircles(grayMask, cv2.HOUGH_GRADIENT, dp, 40, param1=10, param2=30, minRadius=20, maxRadius=70)
Затем для каждого круга я выбрал окружность:
def getROI(frame, x, y, r):
return frame[int(y-r/2):int(y+r/2), int(x-r/2):int(x+r/2)]
После этого я вычисляю самый доминирующий цвет в регионе, используя kmeans и цветовые маски:
COLOR_NAMES = [RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, PURPLE, RED_2]
COLOR_RANGES_HSV = {
"red": [(0, 50, 10), (10, 255, 255)],
"orange": [(10, 50, 10), (25, 255, 255)],
"yellow": [(25, 50, 10), (35, 255, 255)],
"green": [(35, 50, 10), (80, 255, 255)],
"cyan": [(80, 50, 10), (100, 255, 255)],
"blue": [(100, 50, 10), (130, 255, 255)],
"purple": [(130, 50, 10), (170, 255, 255)],
"red ": [(170, 50, 10), (180, 255, 255)]
}
def getMask(frame, color):
blurredFrame = cv2.GaussianBlur(frame, (3, 3), 0)
hsvFrame = cv2.cvtColor(blurredFrame, cv2.COLOR_BGR2HSV)
colorRange = COLOR_RANGES_HSV[color]
lower = np.array(colorRange[0])
upper = np.array(colorRange[1])
colorMask = cv2.inRange(hsvFrame, lower, upper)
colorMask = cv2.bitwise_and(blurredFrame, blurredFrame, mask=colorMask)
return colorMask
def getDominantColor(roi):
roi = np.float32(roi)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 4
ret, label, center = cv2.kmeans(roi, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
center = np.uint8(center)
res = center[label.flatten()]
res2 = res.reshape(roi.shape)
pixelsPerColor = []
for color in COLOR_NAMES:
mask = getMask(res2, color)
greyMask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
count = cv2.countNonZero(greyMask)
pixelsPerColor.append(count)
return COLOR_NAMES[pixelsPerColor.index(max(pixelsPerColor))]
Все вместе:
def detect():
circles = detector.detectCirclesWithDp(imgCopy)
if circles is not None:
for circle in circles[0, :]:
if imageUtils.inFrame(img, circle[0], circle[1]):
roi = imageUtils.getROI(imgCopy, circle[0], circle[1], circle[2])
color = colorlabeler.getDominantColor(roi)
cv2.circle(img, (circle[0], circle[1]), circle[2], colorlabeler.COLORS_RGB["green"], 1)
cv2.circle(img, (circle[0], circle[1]), 2, colorlabeler.COLORS_RGB["green"], 2)
cv2.putText(img, color, (int(circle[0] + 40), int(circle[1] + 20)), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
colorlabeler.COLORS_RGB["green"])
while True:
cv2.imshow("frame", img)
if cv2.waitKey(20) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
И, наконец, результат:
![enter image description here](https://i.stack.imgur.com/sDheg.png)