#!/usr/bin/python

# find_sub_image.py
#       --copyright--                   Copyright 2013 (C) Tranzoa, Co. All rights reserved.    Warranty: You're free and on your own here. This code is not necessarily up-to-date or of public quality.
#       --url--                         http://www.tranzoa.net/tzpython/
#       --email--                       pycode is the name to send to. tranzoa.com is the place to send to.
#       --bodstamps--
#       July 10, 2013           bar
#       --eodstamps--
##      \file
#       \namespace              tzpython.find_sub_image
#
#
#       Find a sub-image inside bigger images.
#
#


import  os
import  sys

numpy   = None      # install it, buddy
try     :
    import  numpy
except ImportError :
    pass

cv2 = None          # install it, buddy
try :
    import  cv2
except ImportError :
    pass

import  tzlib


help_str    = """
%s (options)    small_image     ambiguous_image_file_name...

Options:
    --at_least      number      The match must be at least the given value, 0.0 ... 1.0.
                                0.0  (the default) means include all.
                                0.99 means include very, very close matches, only.
    --sub_dirs                  Include matching files in subdirectories.

Find the given 'small_image' inside the given image files.
Print the X/Y offsets and close-ness of the best bet for the small image.

"""

#
#
if __name__ == '__main__' :

    import  TZCommandLineAtFile


    program_name    = sys.argv.pop(0)

    TZCommandLineAtFile.expand_at_sign_command_line_files(sys.argv)

    sub_dirs        = False
    cutoff          = 0.0

    while True :
        oi  = tzlib.array_find(sys.argv, [ "--help", "-h", "-?", "/?", "/h", "/H" ] )
        if  oi < 0 :    break
        del sys.argv[oi]
        print help_str % ( os.path.basename(program_name) )
        sys.exit(254)


    while True :
        oi  = tzlib.array_find(sys.argv, [ "--at_least", "--atleast", "--at-least", "--cutoff", "--quality", ] )
        if  oi < 0  : break
        del sys.argv[oi]
        cutoff      = float(sys.argv.pop(oi))

    while True :
        oi  = tzlib.array_find(sys.argv, [ "--sub_dirs", "--subdirs", "--sub-dirs", "--sub_dir", "--subdir", "--sub-dir", "--sd", "-s", ] )
        if  oi < 0 :    break
        del sys.argv[oi]
        sub_dirs    = True                  # search sub-directories


    if  not numpy :
        print >>sys.stderr, "Please install numpy!"
        sys.exit(101)
    if  not numpy :
        print >>sys.stderr, "Please install opencv!"
        sys.exit(102)


    if  not len(sys.argv) :
        print >>sys.stderr, "Please tell me the small image file to look for!"
        sys.exit(103)

    tpn     = sys.argv.pop(0)
    tpi     = cv2.imread(tpn)
    h       = tpi.shape[0]
    w       = tpi.shape[1]

    afns    = {}
    while len(sys.argv) :
        fn  = sys.argv.pop(0)
        fns = tzlib.ambiguous_file_list(fn, do_sub_dirs = sub_dirs)
        if  not len(fns) :
            print >>sys.stderr, "No file found: %s!" % fn
            sys.exit(111)
        afns.update(tzlib.make_dictionary(fns))

    fns = afns.keys()
    fns.sort(lambda a, b : cmp(a.lower(), b.lower()))

    print "    X     Y Qual  File name"
    for fn in fns :
        try :
            im      = cv2.imread(fn)
            if  (im.shape[0] < h) or (im.shape[1] < w) :
                raise cv2.error
            r       = cv2.matchTemplate(tpi, im, cv2.TM_CCOEFF_NORMED)
            if  r.max() >= cutoff :
                y, x    = numpy.unravel_index(r.argmax(), r.shape)
                print "%5u %5u %5.3f %s" % ( x, y, r.max(), fn, )
            pass
        except cv2.error :
            if  not cutoff :
                print " None  None None  %s" % fn
            pass
        pass
    pass

#
#
#
# eof
