Hello the OpenCV community :)
I trying to write an algorithm to count dots (cells) on an image.
Here is the script I've made so far :
import numpy as np
import cv2
import os
for dirname in os.listdir("images/"):
for filename in os.listdir("images/" + dirname + "/"):
# Image read
img = cv2.imread("images/" + dirname + "/" + filename, 0)
# Denoising
denoisedImg = cv2.fastNlMeansDenoising(img);
# Threshold (binary image)
# thresh – threshold value.
# maxval – maximum value to use with the THRESH_BINARY and THRESH_BINARY_INV thresholding types.
# type – thresholding type
th, threshedImg = cv2.threshold(denoisedImg, 200, 255,cv2.THRESH_BINARY_INV|cv2.THRESH_OTSU) # src, thresh, maxval, type
# Perform morphological transformations using an erosion and dilation as basic operations
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
morphImg = cv2.morphologyEx(threshedImg, cv2.MORPH_OPEN, kernel)
# Find and draw contours
contours, hierarchy = cv2.findContours(morphImg, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contoursImg = cv2.cvtColor(morphImg, cv2.COLOR_GRAY2RGB)
cv2.drawContours(contoursImg, contours, -1, (255,100,0), 3)
cv2.imwrite("results/" + dirname + "/" + filename + "_result.tif", contoursImg)
textFile = open("results/results.txt","a")
textFile.write(filename + " Dots number: {}".format(len(contours)) + "\n")
textFile.close()
Here is my input image :
Here is my result :
For now this script works pretty well with that input but when I switch to other inputs like this one :
I get a very blobby result :
I would like to be able to only keep the dots which are :
- Well rounded
Or :
- Which are in the top 10% of the other dots in terms of brightness
- Which are "big" enough (relative to the image so let's say eliminate dots which are in the bottom 10% in terms of surface).
I read things about creating a "is_contour_bad" function which I could use to determine if a contour is bad and should be removed.
https://www.pyimagesearch.com/2015/02/09/removing-contours-image-using-python-opencv/
I tried to implement it but didn't get any results. Still, the idea seems good to me.
I also though of adjusting the threshold and erosions/dilatations depending of the image but really the best would be to be able to act on each parameters enumerated before. Still if you have ideas to automatically find the useful properties of an image to apply the right filters on it, it can be interesting.
If you have any idea or piece of code, even small, to help me reach that goal it would be awesome.
Thanks in advance for your help.