Search code examples
opencvcomputer-visiongeometryhough-transformscikit-image

Find coins on image


I'm trying to find coins at different images and mark their location. Coins always are perfect circles (not ellipses), but they can touch or even overlap. Here are some example images, as well as results of my tries (a Python script using skimage and its outputs), but it doesn't seem to perform well.

The script:

def edges(img, t):
    @adapt_rgb(each_channel)
    def filter_rgb(image):
        sigma = 1
        return feature.canny(image, sigma=sigma, low_threshold=t/sigma/2, high_threshold=t/sigma)

    edges = color.rgb2hsv(filter_rgb(img))
    edges = edges[..., 2]
    return edges

images = io.ImageCollection('*.bmp', conserve_memory=True)

for i, im in enumerate(images):
    es = edges(im, t=220)
    output = im.copy()
    circles = cv2.HoughCircles((es*255).astype(np.uint8), cv2.cv.CV_HOUGH_GRADIENT, dp=1, minDist=50, param2=50, minRadius=0, maxRadius=0)

    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)

    # now es is edges
    # and output is image with marked circles

A couple of example images, with detected edges and circles:

I am using canny edge detection & hough transform, which is the most common way to detect circles. However, with the same parameters it finds almost nothing on some photos, and finds way too many circles on other.

Can you give me any pointers and suggestions on how to do this better?


Solution

  • I ended up using dlib's object detector and it performed very well. The detector can be easily applied for detecting any kind of objects. For some related discussion see the question topic on reddit.