observer7
observer7

Reputation: 45

How can I use python cv2.SimpleBlobDetector to detect the single largest spot in an image?

I've used cv2 in python to locate contours, find the portion of the image that I'd like to process, and now I need to locate the center of the largest spot in images like below but I guess I'm not understanding how the params work because it identifies other smaller points but never the larger spot that I'm trying to detect. I'm using the following test code:

params = cv2.SimpleBlobDetector_Params()

params.filterByCircularity = True
params.minCircularity = 0.1

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(cropped_img)
for kp in keypoints:
    print("(%d, %d) size=%.1f resp=%.1f" % (kp.pt[0], kp.pt[1], kp.size, kp.response))


im_with_keypoints = cv2.drawKeypoints(cropped_img, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imwrite(img_path.replace('.png', '-cropped2.png'), im_with_keypoints)

Perhaps I'm approaching this wrong with the values I've tested with, or using the wrong params altogether, but some help would be appreciated. I'm trying to detect the larger blob indicated by the red arrow in the first image. Running this code on the first image produces the second image.

cropped_img cropped_img2

Upvotes: 0

Views: 747

Answers (1)

observer7
observer7

Reputation: 45

So another day of research and the solution is to use a structuring element rather than a blob detector. In this case the blob is not detected due the the intersecting lines, it would work if isolated from the lines. Searching the image for a structured element of a certain size works well. I thought I'd post this code snippet to answer my own question in case someone happens onto this question, it might lead them down another path.

Creating a structuring element is the solution to this sort of image.

gray = cv2.cvtColor(cropped_img,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
round_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (10,10))
detected_ball = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, round_kernel, iterations=2)
cnts = cv2.findContours(detected_ball, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
color = cv2.cvtColor(gray,cv2.COLOR_GRAY2BGR)
for c in cnts:
    x,y,w,h = cv2.boundingRect(c)
    if x > 1 and y > 1:
        cv2.drawContours(color, [c], -1, (0,0,255), 3)

Result: cropped_img_morph

Upvotes: 2

Related Questions