fecavy
fecavy

Reputation: 187

Detecting binary blobs in OpenCV

I have some colored rectangles in my image that I successfully recognize by HSV thresholding. The result looks like this: mask image

Now I want to detect the big blob as one point. I tried it with cv2.SimpleBlobDetector() and custom parameters:

import cv2
import numpy as np

mask = cv2.imread('mask.png')
original = cv2.imread('original.png')
params = cv2.SimpleBlobDetector_Params()
# thresholds
params.minThreshold = 10
params.maxThreshold = 200
#params.thresholdStep = 20

# filter by area
params.filterByArea = True
params.minArea = 1
params.maxArea = 10000

# filter by circularity
params.filterByCircularity = False

# filter by convexity
params.filterByConvexity = False

# filter by inertia
params.filterByInertia = False

detector = cv2.SimpleBlobDetector(params)

keypoints = detector.detect(mask)
img_keypoints = cv2.drawKeypoints(original, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imwrite('keypoints.png', img_keypoints)

This is how the result AND the original picture looks like: keypoints and original

I would expect a red point sitting in the center of the green point.

How can I fix this? Help is very appreciated.

EDIT: I forgot to mention: Is it really necessary to generate multiple binary images in cv2.SimpleBlobDetector() since I already have a binary image as input? Is it OK to change the values to the following:

params.minThreshold = 127
params.maxThreshold = 127

to reduce unnecessary CPU usage by generating binary images?

EDIT2 : Please note that I'm using OpenCV 2, not 3

Thank you.

Upvotes: 2

Views: 4153

Answers (1)

Jeru Luke
Jeru Luke

Reputation: 21233

When using cv2.SimpleBlobDetector(), it looks for blobs that are of a darker shade. In your case, the rectangle in mask is in white while the rest of the image is dark. As a result it is unable to find any blobs for the custom parameters set.

I just made a few changes to the existing code:

  1. Read the mask as a grayscale image not a color image:

mask = cv2.imread('mask.png', 0)

  1. Convert the mask to a binary image with the rectangle highlighted in dark:

ret, mask = cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY_INV)

Proceeding from here using you code gave the following result as you expected.

Result:

enter image description here

Upvotes: 3

Related Questions