%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])
/Library/Python/2.7/site-packages/matplotlib-override/matplotlib/pyplot.py:412: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_num_figures`). max_open_warning, RuntimeWarning)
scenes
['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', '14150358928_e39ffe62d3_k.jpg']
whs
[(67, 108), (61, 41), (68, 47), (64, 37), (88, 51), (61, 40), (60, 42), (65, 46), (65, 88), (61, 87), (60, 35), (63, 37), (76, 44), (61, 35), (82, 48), (62, 41), (65, 38), (68, 41), (98, 56), (61, 41), (79, 50), (61, 42), (82, 51), (65, 44), (63, 37), (69, 40), (63, 29), (95, 162), (69, 48), (72, 50), (61, 35), (87, 69), (99, 143), (61, 35), (60, 41), (69, 40), (75, 44), (60, 38)]
corners
[(1493, 1109), (507, 561), (22, 675), (1003, 834), (881, 1025), (1469, 44), (1853, 1244), (977, 777), (297, 652), (103, 845), (431, 886), (835, 56), (1961, 1048), (1674, 24), (1701, 127), (724, 741), (1423, 482), (1771, 984), (160, 487), (1225, 24), (172, 684), (757, 848), (999, 1263), (1978, 893), (194, 927), (677, 598), (102, 294), (776, 1043), (1235, 319), (1304, 361), (1131, 1067), (944, 1300), (676, 629), (991, 734), (559, 1089), (1857, 392), (1167, 1240), (642, 998)]