Как уменьшить количество ящиков / регионов, созданных в MSER - PullRequest
0 голосов
/ 08 ноября 2018

Я пытался получить меньше ящиков с помощью MSER, так как у меня было слишком много ящиков, созданных на одном и том же элементе неоднократно с очень небольшими различиями в пикселях. Мой код, как показано ниже:

 ## Get mser, and set parameters

   _delta = 10 
_min_area = 250 
_max_area = 800
_max_variation = 10.0 
_min_diversity = 30.0
_max_evolution = 10 
_area_threshold = 12.0
_min_margin = 2.9 
_edge_blur_size = 3  

mser = cv2.MSER_create(_delta,_min_area, _max_area, _max_variation,
_min_diversity,_max_evolution, _area_threshold, _min_margin, _edge_blur_size)

, а затем

 ## Do mser detection, get the coodinates and bboxes on the original  image
      gray = cv2.cvtColor(final, cv2.COLOR_BGR2GRAY)
       coordinates, bboxes = mser.detectRegions(gray)

После этого я вижу, что создано 26K блоков. Какие из параметров можно настроить для меньшего числа регионов (так как они сильно перекрываются). Пожалуйста, помогите?

1 Ответ

0 голосов
/ 28 ноября 2018

_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')
...