Вот один из способов сделать это в Python / OpenCV.
- Считать ввод
- Преобразовать в серый
- Размытие (для сглаживания фона)
- Порог
- Применить морфологию закрыть и открыть для сглаживания
- Получить контуры
- Нарисовать контуры и центроиды
- Сохранить результаты
Ввод:
import cv2
import numpy as np
# read image
img = cv2.imread('circles.png')
# convert to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# apply gaussian blur
blur = cv2.GaussianBlur(gray, (9,9), 0)
# threshold
thresh = cv2.threshold(blur,128,255,cv2.THRESH_BINARY)[1]
# apply close and open morphology to smooth
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9,9))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
# draw contours and get centroids
circles = img.copy()
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
for cntr in contours:
cv2.drawContours(circles, [cntr], -1, (0,0,255), 2)
M = cv2.moments(cntr)
cx = int(M["m10"] / M["m00"])
cy = int(M["m01"] / M["m00"])
x = round(cx)
y = round(cy)
circles[y-2:y+3,x-2:x+3] = (0,255,0)
print(cx,",",cy)
cv2.imshow("thresh", thresh)
cv2.imshow("circles", circles)
cv2.waitKey(0)
cv2.destroyAllWindows()
# save cropped image
cv2.imwrite('circles_thresh.png',thresh)
cv2.imwrite('circles_centroids.png',circles)
Пороговое изображение:
Результирующее изображение с круговыми контурами и центроидами:
Центроиды:
1395 , 937
492 , 891
1617 , 647
978 , 573
1286 , 295
304 , 227
737 , 140