diff options
| author | Ryan Baumann <ryan.baumann@gmail.com> | 2016-08-23 16:14:48 -0400 |
|---|---|---|
| committer | Ryan Baumann <ryan.baumann@gmail.com> | 2016-08-23 16:14:48 -0400 |
| commit | 48b73c35c312d9a00d94f34bffc7d5e1a8f10904 (patch) | |
| tree | 696ce996ed06ea5cd4532e4df476806911b76200 /template_match_multiscale.py | |
| parent | acb4c878bde601de3c792fed38198ad03f69b21e (diff) | |
Initial pass at automatic hi-res NYPL Stereogranimator morphing
Diffstat (limited to 'template_match_multiscale.py')
| -rwxr-xr-x | template_match_multiscale.py | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/template_match_multiscale.py b/template_match_multiscale.py new file mode 100755 index 0000000..4c104af --- /dev/null +++ b/template_match_multiscale.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +# USAGE +# python template_match_multiscale.py --template template.png --image image.tif +# Adapted from: http://www.pyimagesearch.com/2015/01/26/multi-scale-template-matching-using-python-opencv/ + +# import the necessary packages +import numpy as np +import argparse +import glob +import cv2 + +def resize(image, width = None, height = None, inter = cv2.INTER_AREA): + # initialize the dimensions of the image to be resized and + # grab the image size + dim = None + (h, w) = image.shape[:2] + + # if both the width and height are None, then return the + # original image + if width is None and height is None: + return image + + # check to see if the width is None + if width is None: + # calculate the ratio of the height and construct the + # dimensions + r = height / float(h) + dim = (int(w * r), height) + + # otherwise, the height is None + else: + # calculate the ratio of the width and construct the + # dimensions + r = width / float(w) + dim = (width, int(h * r)) + + # resize the image + resized = cv2.resize(image, dim, interpolation = inter) + + # return the resized image + return resized + +# construct the argument parser and parse the arguments +ap = argparse.ArgumentParser() +ap.add_argument("-t", "--template", required=True, help="Path to template image") +ap.add_argument("-i", "--image", required=True, + help="Path to image where template will be matched") +ap.add_argument("-v", "--visualize", + help="Flag indicating whether or not to visualize each iteration") +args = vars(ap.parse_args()) + +# load the image image, convert it to grayscale, and detect edges +template = cv2.imread(args["template"]) +template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY) +template = cv2.Canny(template, 50, 200) +(tH, tW) = template.shape[:2] +cv2.imshow("Template", template) + +imagePath = args["image"] +# load the image, convert it to grayscale, and initialize the +# bookkeeping variable to keep track of the matched region +gray = cv2.imread(imagePath, 0) +found = None + +# loop over the scales of the image +for scale in np.linspace(0.2, 1.0, 20)[::-1]: + # resize the image according to the scale, and keep track + # of the ratio of the resizing + resized = resize(gray, width = int(gray.shape[1] * scale)) + r = gray.shape[1] / float(resized.shape[1]) + + # if the resized image is smaller than the template, then break + # from the loop + if resized.shape[0] < tH or resized.shape[1] < tW: + break + + # detect edges in the resized, grayscale image and apply template + # matching to find the template in the image + edged = cv2.Canny(resized, 50, 200) + result = cv2.matchTemplate(edged, template, cv2.TM_CCOEFF) + (_, maxVal, _, maxLoc) = cv2.minMaxLoc(result) + + # check to see if the iteration should be visualized + if args.get("visualize", False): + # draw a bounding box around the detected region + clone = np.dstack([edged, edged, edged]) + cv2.rectangle(clone, (maxLoc[0], maxLoc[1]), + (maxLoc[0] + tW, maxLoc[1] + tH), (0, 0, 255), 2) + cv2.imshow("Visualize", clone) + cv2.waitKey(0) + + # if we have found a new maximum correlation value, then ipdate + # the bookkeeping variable + if found is None or maxVal > found[0]: + found = (maxVal, maxLoc, r) + +# unpack the bookkeeping varaible and compute the (x, y) coordinates +# of the bounding box based on the resized ratio +(_, maxLoc, r) = found +(startX, startY) = (int(maxLoc[0] * r), int(maxLoc[1] * r)) +(endX, endY) = (int((maxLoc[0] + tW) * r), int((maxLoc[1] + tH) * r)) + +print "%dx%d+%d+%d" % ((endX - startX), (endY - startY), startX, startY) + +# draw a bounding box around the detected result and display the image +# cv2.rectangle(gray, (startX, startY), (endX, endY), (0, 0, 255), 2) +# cv2.imshow("Image", gray) +# cv2.waitKey(0) |
