问题是确定尽可能多且更精确的颗粒,以便将来按直径对它们进行分类
目前,我已经尝试过定义圆的代码,但不够准确,并且确定了很多直径
import cv2
import numpy as np
img = cv2.imread(r'D:\Downloads\bezsveta.jpg', cv2.IMREAD_GRAYSCALE)
img = cv2.equalizeHist(img)
img = cv2.medianBlur(img, 5)
kernel = np.ones((3,3),np.uint8)
img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
retval, threshold = cv2.threshold(img, 120, 255, cv2.THRESH_BINARY_INV)
params = cv2.SimpleBlobDetector_Params()
params.minThreshold = 30
params.maxThreshold = 255
blur = cv2.GaussianBlur(img,(9,9),3)
params.filterByCircularity = True
params.minCircularity = 0.2
params.filterByArea = True
params.minArea = 20
ver = (cv2.__version__).split('.')
if int(ver[0]) < 3 :
detector = cv2.SimpleBlobDetector(params)
else :
detector = cv2.SimpleBlobDetector_create(params)
keypoints = detector.detect(threshold)
im_with_keypoints = cv2.drawKeypoints(img, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# Show keypoints
cv2.imshow("Keypoints", im_with_keypoints)
cv2.waitKey(0)
结果
我对参数进行了迭代,似乎有效,但也许有人会提供有关如何优化的提示?
import cv2
import numpy as np
img = cv2.imread(r'D:\Downloads\bezsveta.jpg', cv2.IMREAD_GRAYSCALE)
original_img = cv2.imread(r'D:\Downloads\bezsveta.jpg')
img = cv2.equalizeHist(img)
img = cv2.bilateralFilter(img, 9, 75, 75)
img = cv2.medianBlur(img, 5)
kernel = np.ones((3,3), np.uint8)
img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
params = cv2.SimpleBlobDetector_Params()
params.minThreshold = 5
params.maxThreshold = 255
params.filterByCircularity = True
params.minCircularity = 0.1
params.filterByArea = True
params.minArea = 50
detector = cv2.SimpleBlobDetector_create(params)
img_with_keypoints = cv2.cvtColor(original_img, cv2.COLOR_BGR2GRAY)
detected_circles = []
for retval in range(80, 255):
_, threshold = cv2.threshold(img, retval, 255, cv2.THRESH_BINARY_INV)
keypoints = detector.detect(threshold)
filtered_keypoints = []
for keypoint in keypoints:
is_overlap = False
for circle in detected_circles + filtered_keypoints:
distance = np.sqrt((keypoint.pt[0] - circle.pt[0])**2 + (keypoint.pt[1] - circle.pt[1])**2)
if distance < (circle.size * 0.5 + keypoint.size * 0.5): # Проверяем перекрытие кругов
is_overlap = True
break
if not is_overlap:
filtered_keypoints.append(keypoint)
detected_circles.extend(filtered_keypoints)
img_with_keypoints = cv2.drawKeypoints(img_with_keypoints, filtered_keypoints, np.array([]), (0, 0, 255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imshow("Keypoints", img_with_keypoints)
cv2.waitKey(1)
print("How much:", len(detected_circles))
cv2.waitKey(0)
cv2.destroyAllWindows()