Detect open circle with Python / OpenCV
Question: I have a picture with random circles shown of which one circle is always open.
The size, position and color of the circles are different each time but the
background is always white.

I want to find the coordinates of the circle which is open programmatically.
Here is a sample picture:

![Sample picture](http://i.stack.imgur.com/oArXc.png)

This picture roughly has coordinates of x:285 y:70. Here is my attempt:

    
    
    import numpy as np
    import argparse
    import cv2
    
    ap = argparse.ArgumentParser()
    ap.add_argument("-i", "--image", required = True, help = "Path to the image")
    args = vars(ap.parse_args())
    
    image = cv2.imread(args["image"])
    black = cv2.imread('black.png')
    output = image.copy()
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    ret,thresh = cv2.threshold(gray,127,255,0)
    contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    cv2.drawContours(black,contours,-1,(250,250,250),2)
    
    newblack = cv2.cvtColor(black, cv2.COLOR_BGR2GRAY)
    
    circles = cv2.HoughCircles(newblack, cv2.cv.CV_HOUGH_GRADIENT, 1, 1,
                  param1=42,
                  param2=35,
                  minRadius=15,
                  maxRadius=50)
    
    if circles is not None:
            circles = np.round(circles[0, :]).astype("int")
    
            for (x, y, r) in circles:
                    cv2.circle(output, (x, y), r, (0, 255, 0), 4)
                    cv2.rectangle(output, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1)
    
            cv2.imshow("output", np.hstack([image, output]))
            print circles
            cv2.waitKey(0)
    

Almost finished!

The param2 Value determines which circle is found. I tweaked my code so it
iterates over param2 values starting with a rather high value of 120.

When it finds a circle it stops.

    
    
    # import the necessary packages
    import numpy as np
    import argparse
    import cv2
    import sys
    
    # construct the argument parser and parse the arguments
    ap = argparse.ArgumentParser()
    ap.add_argument("-i", "--image", required = True, help = "Path to the image")
    args = vars(ap.parse_args())
    
    # load the image, clone it for output, and then convert it to grayscale
    image = cv2.imread(args["image"])
    output = image.copy()
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    str = 120
    
    def findcircle( str ):
        circles = cv2.HoughCircles(gray, cv2.cv.CV_HOUGH_GRADIENT, 1, 1,
        param1=42,
        param2=str,
        minRadius=10,
        maxRadius=100)
    
        if circles is not None:
            circles = np.round(circles[0, :]).astype("int")
            print circles
            sys.exit()
    
        while circles is None:
            str = str-1
            findcircle(str)
    
    findcircle(str)
    

The success rate is around 80-100%

How do change the output of the variable "circles" to only show one circle
incase more then 1 is found and how do I remove unwanted spaces and brackets?


Answer: 
    # import the necessary packages
    import numpy as np
    import argparse
    import cv2
    import sys
    
    # construct the argument parser and parse the arguments
    ap = argparse.ArgumentParser()
    ap.add_argument("-i", "--image", required = True, help = "Path to the image")
    args = vars(ap.parse_args())
    
    # load the image, clone it for output, and then convert it to grayscale
    image = cv2.imread(args["image"])
    output = image.copy()
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    str = 120
    
    def findcircle( str ):
        circles = cv2.HoughCircles(gray, cv2.cv.CV_HOUGH_GRADIENT, 1, 1,
        param1=42,
        param2=str,
        minRadius=10,
        maxRadius=100)
    
        if circles is not None:
            circles = np.round(circles[0, :]).astype("int")
            index = [2]
            new_circles = np.delete(circles[0], index)
            print new_circles
            sys.exit()
    
        while circles is None:
            str = str-1
            findcircle(str)
    
    findcircle(str)
    

