Reputation: 65
First, now i am doing the blob detection by Python2.7 with Opencv. What i want to do is to finish the blob detection after the color detection. i want to detect the red circles(marks), and to avoid other blob interference, i want to do color detection first, and then do the blob detection.
and the image after color detection is binary mask
now i want to do blob detection on this image, but it doesn't work. This is my code.
import cv2
import numpy as np;
# Read image
im = cv2.imread("myblob.jpg", cv2.IMREAD_GRAYSCALE)
# Set up the detector with default parameters.
params = cv2.SimpleBlobDetector_Params()
# Change thresholds
params.minThreshold = 10; # the graylevel of images
params.maxThreshold = 200;
params.filterByColor = True
params.blobColor = 255
# Filter by Area
params.filterByArea = False
params.minArea = 10000
detector = cv2.SimpleBlobDetector(params)
# Detect blobs.
keypoints = detector.detect(im)
# Draw detected blobs as red circles.
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures the size of the circle corresponds to the size of blob
im_with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# Show keypoints
cv2.imshow("Keypoints", im_with_keypoints)
cv2.waitKey(0)`
I am really confused by this code, because it work on this image white dots I think the white dots image is quiet similar with the binary mask,but why cant i do blob detection on the binary image?could anyone tell me the difference or the right code?
Thanks!!
Regards, Nan
Upvotes: 4
Views: 19103
Reputation: 745
It looks that the blob detector has filterByInertia
and filterByConvexity
parameters enabled by default.
You can check this in your system:
import cv2
params = cv2.SimpleBlobDetector_Params()
print params.filterByColor
print params.filterByArea
print params.filterByCircularity
print params.filterByInertia
print params.filterByConvexity
So when you call detector = cv2.SimpleBlobDetector(params)
you are actually filtering also by inertia and convexity with the default min and max values.
If you explicitly disable those filtering criteria:
# Disable unwanted filter criteria params
params.filterByInertia = False
params.filterByConvexity = False
... and then call detector = cv2.SimpleBlobDetector(params)
you get the following image:
The third blob in that image is caused by the white frame on the lower right of your image. You can crop the image, if the frame is always in the same place, or you can use the parameters to filter by circularity and remove the undesired blob:
params.filterByCircularity = True
params.minCircularity = 0.1
And you will finally get:
Upvotes: 8
Reputation: 4441
Easiest way would be what @ArjitMukherjee said.
But I also echo what @meetaig commented initially about difference in structure of blobs in both the images
A clue for why it might not work could be the structure of the blobs. In the first image the white pixels are not all connected to a big blob (meaning there are a few single pixels "floating around") whereas in the second image the circles are perfect blobs
You need to fine tune your algorithm so that it suits/aligns with different structures of blobs
I kind of did quick fine tuning, which could partially meet your requirements:
import cv2
import numpy as np;
# Read image
im = cv2.imread("eRCe1.png", cv2.IMREAD_GRAYSCALE)
# Set up the detector with default parameters.
params = cv2.SimpleBlobDetector_Params()
# Change thresholds
params.minThreshold = 10; # the graylevel of images
params.maxThreshold = 200;
params.filterByColor = True
params.blobColor = 255
# Filter by Area
params.filterByArea = True
params.minArea = 300
detector = cv2.SimpleBlobDetector(params)
# Detect blobs.
keypoints = detector.detect(im)
print keypoints
# Draw detected blobs as red circles.
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures the size of the circle corresponds to the size of blob
im_with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imshow("Keypoints", im_with_keypoints)
cv2.waitKey(0)
Executed the above code on the both the same images that you gave, below are the outputs
Sample 1:
Sample 2:
Upvotes: 0
Reputation: 1516
Its an opencv bug in the filter by color . All you need to do is to invert the color of the image -> Detect Blobs -> Invert again to get back to the original color
import cv2
import numpy as np;
# Read image
im = cv2.imread("myblob.jpg", cv2.IMREAD_GRAYSCALE)
# Set up the detector with default parameters.
im=cv2.bitwise_not(im)
params = cv2.SimpleBlobDetector_Params()
detector = cv2.SimpleBlobDetector_create(params)
# Detect blobs.
keypoints = detector.detect(im)
im=cv2.bitwise_not(im)
# Draw detected blobs as red circles.
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures the size of the circle corresponds to the size of blob
im_with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# Show keypoints
cv2.imshow("Keypoints", im_with_keypoints)
cv2.waitKey(0)
Upvotes: 3