3

I have read through dozens of questions on this topic here. (see eg: 1, 2, 3). There are a lot of helpful explanations of how to play around with parameters etc, watershedding, etc. Yet no matter what I have tried to put together I am still not managing a halfway-passable count of the cells in my image

Here are two examples of the kind of images I need to process.

cells on grey 1

cells on grey 2

Initially I was trying to count all the cells, but because of the difference in focus at the edges (where it gets blurrier) I thought it might be easier to count cells within a rectangle the user selects.

I was hopeful this would improve the results, but as you can see, HoughCircles is both selecting as circles empty spaces with nothing in them, and missing many cells:

hough circles on grey 1

hough circles on grey 2

Other algorithms I have tried have fared worse.

My code:

cap = cv2.VideoCapture(video_file)
frames = []
while True:
    frame_exists, curr_frame = cap.read()
    if frame_exists:
        frames.append(curr_frame)
    else:
        break
frames = [cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) for frame in frames]

for img in frames:
    circles = cv2.HoughCircles(img,
                       cv2.HOUGH_GRADIENT,
                       minDist=10,
                       dp=1.1,
                       param1=4, #the lower the number the more circles found
                       param2=13,
                       minRadius=4,
                       maxRadius=10)
    if circles is not None:
         circles = np.round(circles[0, :]).astype("int")
         for (x, y, r) in circles:
            cv2.circle(img, (x, y), r, (0, 255, 0), 1)
            cv2.imshow("result", img)

Editing to add in my not helpful preprocessing code:

 denoise = cv2.fastNlMeansDenoising(img, h=4.0, templateWindowSize=15, searchWindowSize=21)
 thresh=cv2.adaptiveThreshold(denoise,255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,41,2)

(and then I passed thresh to HoughCircles instead of img)

It just didn't seem to make any difference... enter image description here enter image description here enter image description here

dWitty
  • 494
  • 9
  • 22
  • 1
    You do no kind of image pre-processing before applying HoughCircles. How about thresholding your source image to get all those bright specks pop a bit more? Some sharpening/blurring/dilation/erosion? How about optimizing the image source? – Patrick Artner Feb 14 '22 at 10:09
  • 1
    I did try doing some, it just seemed to make no difference to the outcome hence why I did not include in question. I have edited the question to include. – dWitty Feb 14 '22 at 11:46
  • HoughCircles is unsuitable here. you _might_ have some luck with template matching. or take absolute difference of picture and a median blur of it (to estimate background), then blur that, and find local maxima. – Christoph Rackwitz Feb 14 '22 at 12:50

1 Answers1

1

I believe that these are not circular enough for Hough to work well, you would have to lower param2 too much to account for the lack of uniformity. I would recommend looking into the cv2.findContours method instead and use your 'thresh' image.

https://docs.opencv.org/4.x/dd/d49/tutorial_py_contour_features.html

p111110
  • 11
  • 1