title: Detect caps on bottles using opencv and python
body: <p>I know that there are a hundred topics about my question in all over the web, but i would like to ask specific for my problem because I tried almost all solutions without any success.</p>
  <p>I am trying to count circles in an image (yes i have already tried hough circles but due to light reflections, i think, on my object is not very robust).
  Then I tried to create a classifier (no success i think there is no enough features so the detection is not good)</p>
  <p>I have also tried HSV conversation and tried to find my object with color (again I had some problems because of the light and the variations of colors)
  As you can see on image, there are 8 caps and i would like to be able to count them.</p>
  <p>Using all of this methods, i was able to detect the objects on an image (because I was optimizing all the parameters of functions for the specific image) but as soon as I load a new, similar, image the results was disappointing.</p>
  <p>Please follow this link to see the <a href="https://dl.dropboxusercontent.com/u/5502709/frame71.jpg" rel="nofollow noreferrer">Image</a></p>
  <p>Bellow you can find parts of everything i have tried:</p>
  <p><strong>1. Hough circles</strong></p>
  <pre><code>img = cv2.imread('frame71.jpg',1)
  
  img = cv2.medianBlur(img,5)
  cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
  if img == None:
      print &quot;There is no image file. Quiting...&quot;
      quit()
  
  circles = cv2.HoughCircles(img,cv.CV_HOUGH_GRADIENT,3,50,
                              param1=55,param2=125,minRadius=25,maxRadius=45)
  
  circles = np.uint16(np.around(circles))
  for i in circles[0,:]:
      # draw the outer circle
      cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2)
      # draw the center of the circle
      cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3)
  
  print len(circles[0,:])
  cv2.imshow('detected circles',cimg)
  cv2.waitKey(0)
  cv2.destroyAllWindows()
  </code></pre>
  <p><strong>2. HSV Transform, color detection</strong></p>
  <pre><code>def image_process(frame, h_low, s_low, v_low, h_up, s_up, v_up, ksize):
    temp = ksize
    if(temp%2==1):
     ksize = temp
    else:
     ksize = temp+1
    #if(True):
    # return frame
    #thresh = frame
    #try:
    #TODO: optimize as much as possiblle this part of code
    try:
     hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
     lower = np.array([h_low, s_low, v_low],np.uint8)
     upper = np.array([h_up,s_up,h_up],np.uint8)
     mask = cv2.inRange(hsv, lower, upper)
     res = cv2.bitwise_and(hsv,hsv, mask= mask)
     thresh = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY)
     #thresh = cv2.threshold(res, 50, 255, cv2.THRESH_BINARY)[1]
     thresh = cv2.threshold(thresh, 50, 255, cv2.THRESH_BINARY)[1]
     thresh = cv2.medianBlur(thresh,ksize)
    except Exception as inst:
      print type(inst)
     #cv2.imshow('thresh', thresh)
    return thresh
  </code></pre>
  <p><strong>3. Cascade classifier</strong></p>
  <pre><code>img = cv2.imread('frame405.jpg', 1)
  cap_cascade = cv2.CascadeClassifier('haar_30_17_16_stage.xml')
  caps = cap_cascade.detectMultiScale(img, 1.3, 5)
  #print caps
  for (x,y,w,h) in caps:
      cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0),2)
  
  
  #cv2.rectangle(img, (10,10),(100,100),(0,255,255),4)
  
  cv2.imshow('image', img)
  cv2.waitKey(0)
  cv2.destroyAllWindows()
  
  quit()
  </code></pre>
  <p>About training the classifier I really used a lot of variations of images, samples, negatives and positives, number of stages, w and h but the results was not very accurate.</p>
  <p>Finally I would like to know from your experience which is <strong>the best method I should follow</strong> and I will stick on that in order to optimize my detection. Keep in mind that all images are similiar but NOT identical. There are some differences due to light, movement etc</p>
  <p>Than you in advance,</p>