4

I'm trying to use simple blob detector as described here, however a simplest possible code I've hacked does not seem to yield any results:

img = cv2.imread("detect.png")
detector = cv2.SimpleBlobDetector_create()
keypoints = detector.detect(img)

This code yields empty keypoints array:

[]

The image I'm trying to detects the blobs in is:

enter image description here

I would expect at least 2 blobs to be detected -- according to the documentation simpleblobdetector detects dark blobs and the image does contain 2 of those.

I know it is probably something embarassingly simple I'm missing here, but I cant seem to figure out what it is. My wild guess is, that it has to do something with the circularity of the blob, but trying all kinds of filter parameters I can't seem to figure out the right circularity parameters.

Update: As per the comment below, where it has been suggested that I should invert my image, despite what the documentations suggests (unless I'm misreading it), I've tried to invert it and run the sample again:

img = cv2.imread("detect.png")
img = cv2.bitwise_not(img)
detector = cv2.SimpleBlobDetector_create()
keypoints = detector.detect(img)

enter image description here

However, as I suspected this gives the same results - no detections:

[]
2
  • 1
    you need white blobs on black background, invert your image Commented Oct 30, 2018 at 13:27
  • As I said the documentation says: Default values of parameters are tuned to extract dark circular blobs. Am I misreading this? Commented Oct 30, 2018 at 13:53

1 Answer 1

8

The problem is the parameters :) and for the bottom blob is too close to the border...

You can take a look to the default parameters in this github link. And an interesting graph at the end of this link where you can check how the different parameters will influence the result.

Basically you can see that by default it is filtered by inertia, area and convexity. Now, if you remove the convexity and inertia filters, it will mark the top one. If you remove the area filter, still it will show only the top blob... The main issue with the bottom one is that it is too close to the border... and seems not to be a "blob" for the detector... but if add a small border to the image, it will appear. Here is the code I used for it:

import cv2
import numpy as np
img = cv2.imread('blob.png')
# create the small border around the image, just bottom
img=cv2.copyMakeBorder(img, top=0, bottom=1, left=0, right=0, borderType= cv2.BORDER_CONSTANT, value=[255,255,255] ) 

# create the params and deactivate the 3 default filters
params = cv2.SimpleBlobDetector_Params()
params.filterByArea = False
params.filterByInertia = False
params.filterByConvexity = False

# detect the blobs
detector = cv2.SimpleBlobDetector_create(params)
keypoints = detector.detect(img)

# display them
img_with_keypoints = cv2.drawKeypoints(img, keypoints, outImage=np.array([]), color=(0, 0, 255),flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imshow("Frame", img_with_keypoints)
cv2.waitKey(0)
cv2.destroyAllWindows()

and the resulting image:

enter image description here

And yes, you can achieve similar results without deactivating the filters but rather changing the parameters of it. For example, these parameters worked with exactly the same result:

params = cv2.SimpleBlobDetector_Params()
params.maxArea = 100000
params.minInertiaRatio = 0.05
params.minConvexity = .60
detector = cv2.SimpleBlobDetector_create(params)

It will heavily depend on the task at hand, and what are you looking to detect. And then play with the min/max values of each filter.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I have suspected the parameters would be to "blame" for :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.