Распознание шаров cv Python
Я не програмист, физик, так что мне нужно максимально простое и понятное решение.
У меня есть вот такие картинки:

Мне на них нужно распознать положение центров и радиусы красных шаров. Я делаю это вот так:
import cv2
import numpy as np
# Read image
img = cv2.imread('beads.jpg')
# Convert to HSV and keep the hue channel
hue = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)[:,:,0]
# beads are red but on the blue side, so very bright hues
# so threshold hue at 165 (out of 180)
thresh = cv2.threshold(hue, 165, 255, cv2.THRESH_BINARY)[1]
# apply morphology to fill beads and remove excess spots
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
morph = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (6,6))
morph = cv2.morphologyEx(morph, cv2.MORPH_CLOSE, kernel)
# get contours and enclosing circles
contours = cv2.findContours(morph, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
circles = img.copy()
num_circles = len(contours)
ave = 0
for cntr in contours:
center, radius = cv2.minEnclosingCircle(cntr)
cx = int(round(center[0]))
cy = int(round(center[1]))
rr = int(round(radius))
# draw enclosing circle over beads
cv2.circle(circles, (cx,cy), rr, (0, 255, 0), 2)
# cumulate radii for average
ave = ave + radius
# print average radius
ave_radius = ave / num_circles
print("average radius:", ave_radius)
print ("number of circles:", num_circles)
# save results
cv2.imwrite('beads_thresh.jpg', thresh)
cv2.imwrite('beads_morph.jpg', morph)
cv2.imwrite('beads_circles.jpg', circles)
cv2.imshow('thresh', thresh)
cv2.imshow('morph', morph)
cv2.imshow('circles', circles)
cv2.waitKey(0)
cv2.destroyAllWindows()
В итоге меня получается распознать бОльшую часть шаров (попадаю в 1 \sigma интервал)
Однако из за бликов некоторые шары дублируются, некоторые вложены и программа очевидно работает неправильно. Может следует наложить на фотографию какой то фильтр который сможет убрать блики. Или может можно как то изменить настройки классификатора cv2, что бы он отсеивал блики. Пока я удаляю шары которые очень маленькие или большие, но теряю много важной информации. Как можно исправить мою проблему.
Ответы (1 шт):
Попробуйте использовать эту функцию, тут можно задать расстояние между окружностями, min и max радиус окружностей
А так, без знаний Computer Vision только методом перебора и отладки можно решить вашу задачу)
circles = cv.HoughCircles(gray, cv.HOUGH_GRADIENT, 1, rows / 8,
param1=100, param2=30,
minRadius=1, maxRadius=30)
https://docs.opencv.org/3.4/d4/d70/tutorial_hough_circle.html

