Search code examples
image-processingopencv3.0scikit-image

Approximately locate an image within another


I have this image of the world : World map here And this image of europe : Europe 1919 What technique could I use to approximately locate the image of europe within the world map?


Solution

  • Template matching is a technique for finding similar images within larger images, but it requires the template to be of the same size as in the sub-image. In this example OpenCV was used, but it can also be done using scikit-image.

    import cv2
    from imageio import imread
    
    img = imread("https://i.sstatic.net/OIsWn.png", pilmode="L") 
    template = imread("https://i.sstatic.net/fkNeW.png", pilmode="L")
    
    # threshold images for equal colours
    img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)[1]
    template = cv2.threshold(template, 127, 255, cv2.THRESH_BINARY)[1]
    
    aspect_ratio = template.shape[1] / template.shape[0]
    
    # estimate the width and compute the height based on the aspect ratio
    w = 380
    h = int(w / aspect_ratio)
    
    # resize the template to match the sub-image as best as possible
    template = cv2.resize(template, (w, h))
    
    result = cv2.matchTemplate(img, template, cv2.TM_CCOEFF)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    
    top_left = max_loc
    bottom_right = (top_left[0] + w, top_left[1] + h)
    
    cv2.rectangle(img, top_left, bottom_right, 127, 3)
    
    cv2.imwrite("europe_bounding_box.png", img)
    

    Result:

    europe_bounding_box.png

    Although this example uses a predetermined estimated width, it is also possible to test a range of possible widths and determine which value results in the best match.