Search code examples
pythonimagenumpyimage-processingscikit-image

Search for all templates using scikit-image


I am trying to follow the tutorial from scikit-image regarding Template Matching (check it here). Themplate matching

Using just this example, I would like to find all matching coins (maxima) in the image, not only this one which gave the highest score. I was thinking about using:

maxima = argrelextrema(result, np.greater)

but the problem is that it finds also very small local maxima, which are just a noise. Is there any way to screen numpy array and find the strongest maxima? Thanks!


Solution

  • I have been digging and found some solution but unfortunately I am not sure if I know what exactly is done in the script. I have slightly modified script found here:

    neighborhood_size = 20   #how many pixels
    threshold = 0.01  #threshold of maxima?
    
    data_max = filters.maximum_filter(result, neighborhood_size)
    maxima = (result == data_max)
    data_min = filters.minimum_filter(result, neighborhood_size)
    diff = ((data_max - data_min) > threshold)
    maxima[diff == 0] = 0
    
    x_image,y_image = [], []
    temp_size = coin.shape[0]
    
    labeled, num_objects = ndimage.label(maxima)
    slices = ndimage.find_objects(labeled)
    x, y = [], []
    for dy,dx in slices:
        x_center = (dx.start + dx.stop - 1)/2
        x.append(x_center)
        y_center = (dy.start + dy.stop - 1)/2
        y.append(y_center)
    
    fig, (raw,found) = plt.subplots(1,2)
    raw.imshow(image,cmap=plt.cm.gray)
    raw.set_axis_off()
    found.imshow(result)
    found.autoscale(False)
    found.set_axis_off()
    plt.plot(x,y, 'ro')
    plt.show()
    

    and does this: Found all maxima

    I also realized, that coordinates of found peaks are shifted in comparison to raw image. I think the difference comes from the template size. I will update when I will find out more.

    EDIT: with slight code modification I was able also to find places on the input image:

    x_image_center = (dx.start + dx.stop - 1 + temp_size) / 2
    x_image.append(x_image_center)
    y_image_center = (dy.start + dy.stop - 1 + temp_size) / 2
    y_image.append(y_image_center)
    

    Find all patterns in the image with python