_delta является наиболее важным параметром для уменьшения количества ящиков. Попробуйте поднять его до 25. Чем выше _delta, тем меньше капель вы получите.
- _min_area - самый маленький шарик
- _max_area - самый большой шарик
- _min_diversity - Поднимите, чтобы уменьшить количество перекрывающихся капель
- _max_variation - Повышение для уменьшения областей с высокой дисперсией
Для получения дополнительной информации
После этого я бы проверил bbox'ы, чтобы отфильтровывать перекрывающие BLOB-объекты
Пример кода
import cv2
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
img = cv.imread('input_img.png')
iou_th = 0.95
mser = cv2.MSER_create(_delta=10, _min_area=1000, _max_area=int(0.1 * np.pi * (img.shape[0] /2)**2), _max_variation=0.1)
regions, bboxes = mser.detectRegions(img)
hulls = [cv2.convexHull(p.reshape(-1, 1, 2)) for p in regions]
# Debug plot
img_ = img.copy()
cv2.polylines(img_, hulls, 1, (255, 0, 0), thickness=1)
fig, ax = plt.subplots(figsize=(10, 6))
ax.imshow(img_)
ax.set_title('MSER with overlapping regions')
size_dict = {k: len(region) for k, region in enumerate(regions)}
# Cull overlapping blobs
graph = nx.Graph()
graph.add_nodes_from(range(len(hulls)))
for i, cnt in enumerate(hulls):
for j, cnt in enumerate(hulls):
if i >= j:
continue
box_i = bboxes[i]
box_j = bboxes[j]
tl_i = box_i[:2]
tl_j = box_j[:2]
br_i = tl_i + box_i[2:]
br_j = tl_j + box_j[2:]
tl = np.maximum(tl_i, tl_j)
br = np.minimum(br_i, br_j)
intersected_rect = br - tl
intersection = np.prod(intersected_rect) if intersected_rect[0] > 0 and intersected_rect[1] > 0 else 0
union = np.prod(box_i[2:]) + np.prod(box_j[2:]) - intersection
iou = intersection / union
if iou > iou_th:
graph.add_edge(i, j, iou=iou)
# make list of unique regions - pick the smallest region
trees = list(nx.connected_component_subgraphs(graph))
unique_blobs = []
for tree in trees:
# Choose the smallest region
smallest_idx = None
smallest_blob = np.inf
for node in tree.nodes():
if size_dict[node] < smallest_blob:
smallest_blob = size_dict[node]
smallest_idx = node
unique_blobs.append(smallest_idx)
unique_blobs = unique_blobs
hulls = [hulls[k] for k in unique_blobs]
regions = [regions[k] for k in unique_blobs]
bboxes = [bboxes[k] for k in unique_blobs]
size_dict = {k: len(region) for k, region in enumerate(regions)}
# debug plot
img_ = img.copy()
cv2.polylines(img_, hulls, 1, (255, 0, 0), thickness=1)
fig, ax = plt.subplots(figsize=(10, 6))
ax.imshow(img_)
ax.set_title('MSER with unique regions')