0

On my local hard disk I have a directory with thousands of images (they are scanned documents). I have a tiny image (for instance, 200x100 px - this is a signature of a person). I have to find all images which contain this fragment (or similar fragment - different signatures of a person are not pixel-by-pixel identical). How can I do this? Tools suggested in similar questions - for instance in Local image search against a source image? - do not work in my case, because (as far as I understand) they search for similar whole images, while I want to find images containing given fragment.

1 Answers1

1

Since there are no answers yet, I will provide a possible solution (note however, that this is computationally expensive).

You can install OpenCV and compile a program to do such a task.

For more details, consult https://stackoverflow.com/a/29669787/8055533

The relevant code is below:

def find_image(im, tpl):
    im = np.atleast_3d(im)
    tpl = np.atleast_3d(tpl)
    H, W, D = im.shape[:3]
    h, w = tpl.shape[:2]

    # Integral image and template sum per channel
    sat = im.cumsum(1).cumsum(0)
    tplsum = np.array([tpl[:, :, i].sum() for i in range(D)])

    # Calculate lookup table for all the possible windows
    iA, iB, iC, iD = sat[:-h, :-w], sat[:-h, w:], sat[h:, :-w], sat[h:, w:] 
    lookup = iD - iB - iC + iA
    # Possible matches
    possible_match = np.where(np.logical_and(*[lookup[..., i] == tplsum[i] for i in range(D)]))

    # Find exact match
    for y, x in zip(*possible_match):
        if np.all(im[y+1:y+h+1, x+1:x+w+1] == tpl):
            return (y+1, x+1)

    raise Exception("Image not found")

and

>>> from skimage import data
>>> im = gray2rgb(data.coins())
>>> tpl = im[170:220, 75:130].copy()

>>> fig, ax = plt.subplots()
>>> imshow(im)
>>> rect = Rectangle((x, y), tpl.shape[1], tpl.shape[0], edgecolor='r', facecolor='none')
>>> ax.add_patch(rect)