Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect blurry blobs?

I would like to detect all the bright spots in this image (https://i.sstatic.net/3NCKi.png)

The code I've tried is via thresholding, but it only detects the very bright ones. As you can see in the image below.

enter image description here

But some of the spots are out of focus which I need to also detect them. Could you suggest a method? The picture below shows the blurred spots that I'd like to detect in yellow circles

enter image description here

I tried with the following code

import os
import cv2
import numpy as np


path="C:/Slides/Fluoroscent/E_03_G_O_subpics"
imgname="sub_2_4.png"
image = cv2.imread(os.path.join(path,imgname))

#  constants
BINARY_THRESHOLD = 10
CONNECTIVITY = 4
DRAW_CIRCLE_RADIUS = 18
thr=50
#  convert to gray
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

#  threshold the black/ non-black areas
_, thresh = cv2.threshold(gray_image, BINARY_THRESHOLD, thr, cv2.THRESH_BINARY)

#  find connected components
components = cv2.connectedComponentsWithStats(thresh, CONNECTIVITY, cv2.CV_32S)

#  draw circles around center of components
#see connectedComponentsWithStats function for attributes of components variable
centers = components[3]
for center in centers:
    cv2.circle(image, (int(center[0]), int(center[1])), DRAW_CIRCLE_RADIUS, (0,0,255), thickness=1)

cv2.imwrite(os.path.join(path,"result_thresh_"+str(thr)+".png"), image)
cv2.imshow("result", image)
cv2.waitKey(0)
like image 787
Maryam Sadeghi Avatar asked Oct 17 '25 17:10

Maryam Sadeghi


1 Answers

As mentioned in the comments you will get better results by changing the threshold values. I changed the values to 20 and 255 respectively and added erosion to get rid of some noise. You can play around with morphological transformations to get the exact desired result. Read more here .

Code:

import cv2
import numpy as np

kernel = np.ones((5,5),np.uint8)
CONNECTIVITY = 4
DRAW_CIRCLE_RADIUS = 18
img = cv2.imread('blobs.png')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, thresh = cv2.threshold(gray_img, 20, 255, cv2.THRESH_BINARY)
erosion = cv2.erode(thresh,kernel,iterations = 1)

components = cv2.connectedComponentsWithStats(erosion, CONNECTIVITY, cv2.CV_32S)

centers = components[3]
for center in centers:
    cv2.circle(img, (int(center[0]), int(center[1])), DRAW_CIRCLE_RADIUS, (0,0,255), thickness=1)

cv2.imshow('Original', img)
cv2.imshow('Thresh', thresh)
cv2.imshow('Erosion', erosion)
cv2.waitKey(0)

Results:

Threshold Threshold

Erosion erosion

Original with circles

circles

like image 93
Christoffer Avatar answered Oct 20 '25 08:10

Christoffer