Last active
July 22, 2020 15:37
-
-
Save cheng10/34bdf2e2da3048faf428e64907f17ec9 to your computer and use it in GitHub Desktop.
Template Matching using Python and OpenCV with the Help of Scaling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Usage: python scaled_template_matching.py --template tmp.jpg --image img.jpg | |
Installation: | |
pip install opencv-contrib-python numpy imutils | |
blog post about this scale image & cv2.matchTemplate method: | |
https://www.pyimagesearch.com/2015/01/26/multi-scale-template-matching-using-python-opencv/ | |
""" | |
import glob | |
import argparse | |
import numpy as np | |
import imutils | |
import cv2 | |
# 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", "--images", required=True, | |
# help="Path to images where template will be matched") | |
ap.add_argument( | |
"-i", "--image", required=True, | |
help="Path to the 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()) | |
tmp_path = args['template'] | |
img_path = args['image'] | |
res_path = '{}_{}.jpg'.format( | |
tmp_path.strip('.jpg').strip('.jpeg'), | |
img_path.strip('.jpg').strip('.jpeg'), | |
) | |
# load the image image, convert it to grayscale, and detect edges | |
template = cv2.imread(args["template"]) | |
# cv2.imshow("Template", template) | |
# cv2.waitKey(0) | |
# cv2.destroyAllWindows() | |
template = imutils.resize(template, width=200) | |
# cv2.imshow("Template", template) | |
# cv2.waitKey(0) | |
# cv2.destroyAllWindows() | |
template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY) | |
template = cv2.Canny(template, 50, 200) | |
(tH, tW) = template.shape[:2] | |
# cv2.imshow("Template", template) | |
# cv2.waitKey(0) | |
# cv2.destroyAllWindows() | |
# loop over the images to find the template in | |
# for imagePath in glob.glob(args["images"] + "/*.jpg"): | |
for imagePath in glob.glob(args["image"]): | |
# load the image, convert it to grayscale, and initialize the | |
# bookkeeping variable to keep track of the matched region | |
image = cv2.imread(imagePath) | |
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) | |
found = None | |
# loop over the scales of the image | |
for scale in np.linspace(1, 2, 10)[::-1]: | |
# resize the image according to the scale, and keep track | |
# of the ratio of the resizing | |
resized = imutils.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 update | |
# the bookkeeping variable | |
if found is None or maxVal > found[0]: | |
found = (maxVal, maxLoc, r) | |
# unpack the bookkeeping variable 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)) | |
# draw a bounding box around the detected result and display the image | |
cv2.rectangle(image, (startX, startY), (endX, endY), (0, 0, 255), 2) | |
cv2.imshow("Image", image) | |
cv2.waitKey(0) | |
cv2.destroyAllWindows() | |
cv2.imwrite(res_path, image) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment