Sheldon
Sheldon

Reputation: 4675

OpenCV: understanding the filterByArea parameter used in SimpleBlobDetector

I am trying to detect a large stain using OpenCV's SimpleBlobDetector following this SO answer.

Here is the input image:

enter image description here

I first tried working with params.filterByArea = False, which allowed to detect the large black stain:

enter image description here

However, smaller spots also ended up being detected. I therefore toggled params.filterByArea = True hoping to enforce a criterion on object area.

However, when setting params.filterByArea = True with params.minArea = 10 the largest stain is no longer identified:

enter image description here

I tried using other minArea parameters to no avail, even trying a minArea of 0, which should be equivalent to no filtering at all.

What am I missing here?

Upvotes: 2

Views: 44

Answers (1)

LMC
LMC

Reputation: 12877

opencv maxArea param has 5000 as default value. Increasing it could detect blobs bigger than that

import cv2
import numpy as np

def show_keypoints(im, keypoints):
    im_key = cv2.drawKeypoints(im, keypoints, np.array([]), (0, 0, 255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
    cv2.imshow("Keypoints", im_key)
    cv2.waitKey(0)

im_path = "test.png"
im_m = cv2.imread(im_path, cv2.IMREAD_GRAYSCALE)
params = cv2.SimpleBlobDetector_Params()


params.filterByArea = True
params.minArea = 10000
params.maxArea = 50000

detector = cv2.SimpleBlobDetector_create(params)
keypoints = detector.detect(im_m)

show_keypoints(im_m, keypoints)

To print all detector params with default values use

# a map suitable to get configuration from a yaml file
param_map = {"blobColor":  "blob_color",
            "filterByArea":  "filter_by_area",
            "filterByCircularity":  "filter_by_circularity",
            "filterByColor":  "filter_by_color",
            "filterByConvexity":  "filter_by_convexity",
            "filterByInertia":  "filter_by_inertia",
            "maxArea":  "max_area",
            "maxCircularity":  "max_circularity",
            "maxConvexity":  "max_convexity",
            "maxInertiaRatio":  "max_inertia_ratio",
            "maxThreshold":  "max_threshold",
            "minArea":  "min_area",
            "minCircularity":  "min_circularity",
            "minConvexity":  "min_convexity",
            "minDistBetweenBlobs":  "min_dist_between_blobs",
            "minInertiaRatio":  "min_inertia_ratio",
            "minRepeatability":  "min_repeatability",
            "minThreshold":  "min_threshold",
            "thresholdStep":  "threshold_step"}
for k in param_map:
    print(f"{k:<21}: {params.__getattribute__(k)}")

result

blobColor            : 0
filterByArea         : True
filterByCircularity  : False
filterByColor        : True
filterByConvexity    : False
filterByInertia      : False
maxArea              : 7000.0
maxCircularity       : 3.4028234663852886e+38
maxConvexity         : 3.4028234663852886e+38
maxInertiaRatio      : 3.4028234663852886e+38
maxThreshold         : 220.0
minArea              : 500.0
minCircularity       : 0.5
minConvexity         : 0.20000000298023224
minDistBetweenBlobs  : 10.0
minInertiaRatio      : 0.10000000149011612
minRepeatability     : 2
minThreshold         : 50.0
thresholdStep        : 10.0

Upvotes: 4

Related Questions