title: Python OpenCV for template matching
body: <p>I have a small python script using openCV that does template matching in an image and nicely returns a bounding box, as bellow. The script is size invariant as well which makes it more robust. </p>
  
  <p>Given the bounding box returned, how can I <strong>replace</strong> it with another template and save the altered image?</p>
  
  <p>Here is the <a href="https://i.stack.imgur.com/lqXno.png" rel="nofollow noreferrer">original template</a> and the <a href="https://i.stack.imgur.com/wxb6V.jpg" rel="nofollow noreferrer">main image</a></p>
  
  <p><a href="https://i.stack.imgur.com/iEMvtl.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/iEMvtl.jpg" alt="enter image description here"></a></p>
  
  <p>And now I would like to simply replace the exact box with a resized version of template2 below, and save the new image. How can I do that?</p>
  
  <p><a href="https://i.stack.imgur.com/YL4bF.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YL4bF.png" alt="enter image description here"></a></p>
  
  <p>Here is my simple code:</p>
  
  <pre><code># USAGE
  # python match.py --template cod_logo.png --images images
  
  # import the necessary packages
  import numpy as np
  import argparse
  import imutils
  import glob
  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 dir where template will be matched")
  ap.add_argument("-v", "--visualize",
      help="Flag 0 or 1 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)
  
  # loop over the images to find the template in
  for imagePath in glob.glob(args["images"] + "/*.*"):
      # 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(0.2, 1.0, 20)[::-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] &lt; tH or resized.shape[1] &lt; 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 &gt; 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))
  
      # 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)
  </code></pre>