Blob Detector Not working when it should on obvious blobs, makes no sense

asked 2019-05-29 13:19:11 -0600

updated 2019-05-29 18:21:25 -0600

Tetragramm gravatar image

So I have an HSV filtered image that I am trying to do blob detection on but for some reason it is not working. The image is this one: https://i.stack.imgur.com/OhIaY.png

Using the Simple Blob Detector, I get this: https://i.stack.imgur.com/07wl0.png

However, on other samples such as https://i.stack.imgur.com/mYgbc.png, the code works perfectly fine and does the job I want. What parameter do I change? I'm really not sure what's going wrong, this should be working. My code is attached below:

import cv2
import numpy as np
from matplotlib import pyplot as plt
%matplotlib inline
plt.rcParams['figure.figsize'] = [20, 10]

img = cv2.imread('graphenetest.png')
#img = cv2.resize(img,(800,600))

SLG_MIN = np.array([114, 50, 50],np.uint8)
SLG_MAX = np.array([116, 255, 255],np.uint8)

hsv_img = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

frame_threshed = cv2.inRange(hsv_img, SLG_MIN, SLG_MAX)

imagem = cv2.bitwise_not(frame_threshed)

kernel = np.ones((10, 10), np.uint8)
#blur = cv2.morphologyEx(imagem, cv2.MORPH_CLOSE, kernel)
median = cv2.medianBlur(imagem,9)



im = median
plt.imshow(im)
plt.title('Single Layer Graphene Detected')
plt.show()

# Setup SimpleBlobDetector parameters.
params = cv2.SimpleBlobDetector_Params()

# Change thresholds
params.minThreshold = 50
params.maxThreshold = 100


# Filter by Area.
params.filterByArea = True
params.minArea = 10000
params.maxArea = 100000000

params.filterByCircularity = False

params.filterByInertia = False

params.filterByConvexity = False


# Create a detector with the parameters
ver = (cv2.__version__).split('.')
if int(ver[0]) < 3 :
    detector = cv2.SimpleBlobDetector(params)
else : 
    detector = cv2.SimpleBlobDetector_create(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)

img2 = im.copy()
for x in range(1,len(keypoints)):
  img2=cv2.circle(img, (np.int(keypoints[x].pt[0]),np.int(keypoints[x].pt[1])), radius=np.int(keypoints[x].size), color=(255, 0, 0), thickness=10)

# Show blobs
plt.imshow(img)
plt.title('Single Layer Graphene Detected')
plt.show()

cv2.imwrite("SLG.png", img)

I tried messing with the parameters, making minArea = 150 works for the one it otherwise doesn't work for, but doing that screws the other shapes. I even tried adding a constraint to the circle drawing function:

if np.int(keypoints[x].size) >= 500:

but that did not help either. Besides all this parameter messing seems so arbitrary, I want something more systematic.

Here is the original image I am trying to do a detection on: https://imgur.com/a/UKh7Xfu

EDITED TO FIX LINK - Tetragramm

edit retag flag offensive close merge delete

Comments

1

can you try to put your images HERE, not on imgur (where they are not available from certain countries, willl expire, etc.)

use the "upload image" button from the edit menu.

berak gravatar imageberak ( 2019-05-30 00:54:19 -0600 )edit

Will do next time, thanks

gblob445 gravatar imagegblob445 ( 2019-05-30 01:08:20 -0600 )edit