title: Python openCV matchTemplate on grayscale image with masking
body: <p>I have a project where I want to locate a bunch of arrows in images that look like so: <strong>ibb.co/dSCAYQ</strong>
  with the following template: <strong>ibb.co/jpRUtQ</strong></p>
  
  <p>I'm using cv2's template matching feature in Python. My algorithm is to rotate the template 360 degrees and match for each rotation. I get the following result: <strong>ibb.co/kDFB7k</strong></p>
  
  <p>As you can see, it works well except for the 2 arrows that are really close, such that another arrow is in the black region of the template. </p>
  
  <p>I am trying to use a mask, but it seems that cv2 is not applying my masks at all, i.e. no matter what values that mask array has, the matching is the same. Have been trying this for two days but cv2's limited documentation is not helping.</p>
  
  <p>Here is my code:</p>
  
  <pre class="lang-python prettyprint-override"><code>import numpy as np
  import cv2
  import os
  from scipy import misc, ndimage
  
  STRIPPED_DIR = #Image dir
  TMPL_DIR = #Template dir
  MATCH_THRESH = 0.9
  MATCH_RES = 1  #specifies degree-interval at which to match
  
  def make_templates():
      base = misc.imread(os.path.join(TMPL_DIR,'base.jpg')) # The templ that I rotate to make 360 templates
      for deg in range(360):
          print('making template: ' + str(deg))
          tmpl = ndimage.rotate(base, deg)
          misc.imsave(os.path.join(TMPL_DIR, 'tmp' + str(deg) + '.jpg'), tmpl)
  
  def make_masks():
      for deg in range(360):
          tmpl = cv2.imread(os.path.join(TMPL_DIR, 'tmp' + str(deg) + '.jpg'), 0)
          ret2, mask = cv2.threshold(tmpl, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
          cv2.imwrite(os.path.join(TMPL_DIR, 'mask' + str(deg) + '.jpg'), mask)
  
  def match(img_name):
      img_rgb = cv2.imread(os.path.join(STRIPPED_DIR, img_name))
      img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
  
      for deg in range(0, 360, MATCH_RES):
          tmpl = cv2.imread(os.path.join(TMPL_DIR, 'tmp' + str(deg) + '.jpg'), 0)
          mask = cv2.imread(os.path.join(TMPL_DIR, 'mask' + str(deg) + '.jpg'), 0)
          w, h = tmpl.shape[::-1]
          res = cv2.matchTemplate(img_gray, tmpl, cv2.TM_CCORR_NORMED, mask=mask)
          loc = np.where( res &gt;= MATCH_THRESH)
  
          for pt in zip(*loc[::-1]):
              cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
          cv2.imwrite('res.png',img_rgb)
  </code></pre>
  
  <p>Some things that I think could be wrong but not sure how to fix:</p>
  
  <ol>
  <li>The number of channels the mask/tmpl/img should have. I have tried an example with colored 4-channel pngs <a href="https://stackoverflow.com/questions/35642497/python-opencv-cv2-matchtemplate-with-transparency/36047048#comment58966958_35642497">stackoverflow eg.</a>, but not sure how it translates to grayscale or 3-channel jpegs.</li>
  <li>The values of the mask array. e.g. Should masked out pixels be 1 or 255?</li>
  </ol>
  
  <p>Any help is greatly appreciated.</p>
  
  <p><strong>UPDATE</strong>
  I fixed a trivial error in my code; mask=mask must be used in the argument for matchTemplate(). This combined with using mask values of 255 made the difference. However, now I get a ton of false positives like so:
  <strong><a href="http://ibb.co/esfTnk" rel="noreferrer">http://ibb.co/esfTnk</a></strong> Note that the false positives are more strongly correlated than the true positives.
  Any pointers on how to fix my masks to resolve this? Right now I am simply using a black-and-white conversion of my templates.</p>