%matplotlib inline import cv2 from cv2 import cv import matplotlib.pyplot as plt import numpy as np from IPython.display import display, Image as PImage from PIL import Image from glob import glob baseurl = "/Users/mga/Desktop/hack4fi/data/" # taken from https://www.flickr.com/photos/slsarkiva/sets/72157644581542379 images = ["14150358928_e39ffe62d3_k.jpg", "14150359478_e9068c1bb0_k.jpg", "14150363748_15fc880fb5_k.jpg", "14150365358_0d4304a05c_k.jpg", "14150366448_ed7cd1d1a5_k.jpg", "14150368099_ca896719a3_k.jpg", "14150372658_62154f677c_k.jpg", "14150404490_8016758b1d_k.jpg", "14150405960_634206b2c9_k.jpg", "14150409510_a2d2513979_k.jpg", "14150410510_dd2bc28e30_k.jpg", "14150413850_501e87ab29_k.jpg", "14150414830_e7c2c6463e_k.jpg", "14150415010_4c9146f594_k.jpg", "14150415200_fd012b4bd3_k.jpg", "14150422810_8d1a564542_k.jpg", "14150533077_1ebed0b0d8_k.jpg", "14150534587_7fa21f1972_k.jpg", "14150534687_7fef87be81_k.jpg", "14150543547_f0c646a735_k.jpg", "14313883716_f7bdb887a1_k.jpg", "14313897186_df9708311a_k.jpg", "14333682191_cb8b168932_k.jpg", "14333684581_2f3ad497c5_k.jpg", "14333690961_6cab5abac9_k.jpg", "14335350162_02cd300895_k.jpg", "14335350662_418a4c9225_k.jpg", "14335351072_6f8cc1c1d0_k.jpg", "14335352842_735111fb12_k.jpg", "14336267914_f8833a689e_k.jpg", "14336270814_891ae0aa15_k.jpg", "14337016445_923bc0abf9_k.jpg", "14337022265_0e99ee4713_k.jpg", "14337026705_ab2ac044f5_k.jpg", "14337029665_e565809e94_k.jpg", "14357219413_dfc0310475_k.jpg", "14357220853_7576446bde_k.jpg", "14357228353_55c6bc0ff8_k.jpg"] def find_image(from_file, to_file): waldo_img = cv2.imread(from_file) scene_img = cv2.imread(to_file) return best_match(waldo_img, scene_img, 60, 100) # taken wholesale from http://nbviewer.ipython.org/gist/aschn/5861365 def best_match(template_img, scene_img, minsize, maxsize): """ Get the best match for a template image within a scene image, rescaling the template width between minsize and maxsize while maintaining the aspect ratio. Returns two 2-tuples of ints: corner is the (x,y) position of the upper-left corner of the template in the scene wh is (width, height) """ # widths is all the widths to try widths = np.arange(minsize, maxsize, dtype=int) # aspect_ratio is height/width of the template image aspect_ratio = template_img.shape[0] / float(template_img.shape[1]) # heights is all the heights to try heights = np.asarray(aspect_ratio*widths, dtype=int) # best_scores will store the best score for each width best_scores = np.zeros(len(widths)) # best_positions will store the best (x,y) positions of the template for each width best_positions = np.zeros([len(widths), 2], dtype=int) # scan widths for isize in range(widths.size): # log # print "resizing to width = %d" % widths[isize] # resize resized_template_img = cv2.resize(template_img, (widths[isize], heights[isize])) # match scores = cv2.matchTemplate(scene_img, resized_template_img, method=cv2.TM_CCORR_NORMED) # get best score and position min_score, max_score, (min_x, min_y), (max_x, max_y) = cv2.minMaxLoc(scores) # store best score and position best_scores[isize] = max_score best_positions[isize] = [max_x, max_y] # choose best overall match best_isize = np.argmax(best_scores) best_width = widths[best_isize] best_position = best_positions[best_isize] # plot scores plt.plot(widths, best_scores) plt.arrow(widths[best_isize], 0, 0, 1, color='r') plt.xlabel('template width') plt.ylabel('score') # return return tuple(best_positions[best_isize]), (widths[best_isize], heights[best_isize]) def imshow_highlighted(img, corner, wh, rgb=(255,0,0), stroke=5): """ Show an image with a highlighted rectangle. corner is a (x_upperleft, y_upperleft) tuple of ints, wh is a (width, height) tuple of ints, rgb is an optional (r,g,b) tuple (default green), stroke is an optional number of pixels for rectangle stroke (default 5). """ # copy the image so we don't modify the original img_highlighted = img[:,:,[2,1,0]].copy() # add a rectangle cv2.rectangle(img_highlighted, corner, (corner[0]+wh[0], corner[1]+wh[1]), rgb, stroke) # show plt.imshow(img_highlighted) corners = [] whs = [] waldos = [] scenes = [] for i, image in enumerate(images): waldo = images[i] if (i+1 < len(images)): scene = images[i+1] else: scene = images[0] corner, wh = find_image(baseurl+waldo, baseurl+scene) corners.append(corner) whs.append(wh) waldos.append(waldo) scenes.append(scene) scene_img = cv2.imread(baseurl + images[0]) plt.figure() plt.imshow(scene_img) for i,scene in enumerate(scenes): scene_img = cv2.imread(baseurl + scenes[i]) plt.figure() imshow_highlighted(scene_img, corners[i], whs[i]) scenes whs corners