title: Count cells on image using python and OpenCV
body: <p>I'm trying to write an algorithm to count dots (cells) on an image.</p>
  
  <p>Here is the script I've made so far :</p>
  
  <pre><code>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()
  </code></pre>
  
  <p>Here is my input image : 
  <a href="https://i.stack.imgur.com/lFwV9.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/lFwV9.jpg" alt="Input"></a></p>
  
  <p>Here is my result :
  <a href="https://i.stack.imgur.com/QvhEk.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/QvhEk.jpg" alt="Result"></a></p>
  
  <p>For now this script works pretty well with that input but when I switch to other inputs like this one :
  <a href="https://i.stack.imgur.com/F0V8S.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/F0V8S.jpg" alt="Input"></a></p>
  
  <p>I get a very blobby result :</p>
  
  <p><a href="https://i.stack.imgur.com/FPSlX.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/FPSlX.jpg" alt="Result"></a></p>
  
  <p>I would like to be able to only keep the dots which are :</p>
  
  <ul>
  <li>Well rounded</li>
  </ul>
  
  <p>Or :</p>
  
  <ul>
  <li>Which are in the top 10% of the other dots in terms of brightness</li>
  <li>Which are "big" enough (relative to the image so let's say eliminate dots which are in the bottom 10% in terms of surface).</li>
  </ul>
  
  <p>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.</p>
  
  <p><a href="https://www.pyimagesearch.com/2015/02/09/removing-contours-image-using-python-opencv/" rel="nofollow noreferrer">https://www.pyimagesearch.com/2015/02/09/removing-contours-image-using-python-opencv/</a></p>
  
  <p>I tried to implement it but didn't get any results. Still, the idea seems good to me.</p>
  
  <p>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.</p>
  
  <p>If you have any idea or piece of code, even small, to help me reach that goal it would be awesome.</p>
  
  <p>Thanks in advance for your help.</p>