|
| 1 | +#!/usr/bin/python |
| 2 | + |
| 3 | +####################################################### |
| 4 | +# Copyright (c) 2018, ArrayFire |
| 5 | +# All rights reserved. |
| 6 | +# |
| 7 | +# This file is distributed under 3-clause BSD license. |
| 8 | +# The complete license agreement can be obtained at: |
| 9 | +# http://arrayfire.com/licenses/BSD-3-Clause |
| 10 | +######################################################## |
| 11 | + |
| 12 | +from time import time |
| 13 | +import arrayfire as af |
| 14 | +import sys |
| 15 | + |
| 16 | +def normalize(a): |
| 17 | + max_ = float(af.max(a)) |
| 18 | + min_ = float(af.min(a)) |
| 19 | + return (a - min_) / (max_ - min_) |
| 20 | + |
| 21 | +def draw_rectangle(img, x, y, wx, wy): |
| 22 | + print("\nMatching patch origin = ({}, {})\n".format(x, y)) |
| 23 | + |
| 24 | + # top edge |
| 25 | + img[y, x : x + wx, 0] = 0.0 |
| 26 | + img[y, x : x + wx, 1] = 0.0 |
| 27 | + img[y, x : x + wx, 2] = 1.0 |
| 28 | + |
| 29 | + # bottom edge |
| 30 | + img[y + wy, x : x + wx, 0] = 0.0 |
| 31 | + img[y + wy, x : x + wx, 1] = 0.0 |
| 32 | + img[y + wy, x : x + wx, 2] = 1.0 |
| 33 | + |
| 34 | + # left edge |
| 35 | + img[y : y + wy, x, 0] = 0.0 |
| 36 | + img[y : y + wy, x, 1] = 0.0 |
| 37 | + img[y : y + wy, x, 2] = 1.0 |
| 38 | + |
| 39 | + # left edge |
| 40 | + img[y : y + wy, x + wx, 0] = 0.0 |
| 41 | + img[y : y + wy, x + wx, 1] = 0.0 |
| 42 | + img[y : y + wy, x + wx, 2] = 1.0 |
| 43 | + |
| 44 | + return img |
| 45 | + |
| 46 | +def templateMatchingDemo(console): |
| 47 | + |
| 48 | + if console: |
| 49 | + img_color = af.load_image("../../assets/examples/images/square.png", True); |
| 50 | + else: |
| 51 | + img_color = af.load_image("../../assets/examples/images/man.jpg", True); |
| 52 | + |
| 53 | + # Convert the image from RGB to gray-scale |
| 54 | + img = af.color_space(img_color, af.CSPACE.GRAY, af.CSPACE.RGB) |
| 55 | + iDims = img.dims() |
| 56 | + print("Input image dimensions: ", iDims) |
| 57 | + |
| 58 | + # Extract a patch from the input image |
| 59 | + patch_size = 100 |
| 60 | + tmp_img = img[100 : 100+patch_size, 100 : 100+patch_size] |
| 61 | + |
| 62 | + result = af.match_template(img, tmp_img) # Default disparity metric is |
| 63 | + # Sum of Absolute differences (SAD) |
| 64 | + # Currently supported metrics are |
| 65 | + # AF_SAD, AF_ZSAD, AF_LSAD, AF_SSD, |
| 66 | + # AF_ZSSD, AF_LSSD |
| 67 | + |
| 68 | + disp_img = img / 255.0 |
| 69 | + disp_tmp = tmp_img / 255.0 |
| 70 | + disp_res = normalize(result) |
| 71 | + |
| 72 | + minval, minloc = af.imin(disp_res) |
| 73 | + print("Location(linear index) of minimum disparity value = {}".format(minloc)) |
| 74 | + |
| 75 | + if not console: |
| 76 | + marked_res = af.tile(disp_img, 1, 1, 3) |
| 77 | + marked_res = draw_rectangle(marked_res, minloc%iDims[0], minloc/iDims[0],\ |
| 78 | + patch_size, patch_size) |
| 79 | + |
| 80 | + print("Note: Based on the disparity metric option provided to matchTemplate function") |
| 81 | + print("either minimum or maximum disparity location is the starting corner") |
| 82 | + print("of our best matching patch to template image in the search image") |
| 83 | + |
| 84 | + wnd = af.Window(512, 512, "Template Matching Demo") |
| 85 | + |
| 86 | + while not wnd.close(): |
| 87 | + wnd.set_colormap(af.COLORMAP.DEFAULT) |
| 88 | + wnd.grid(2, 2) |
| 89 | + wnd[0, 0].image(disp_img, "Search Image" ) |
| 90 | + wnd[0, 1].image(disp_tmp, "Template Patch" ) |
| 91 | + wnd[1, 0].image(marked_res, "Best Match" ) |
| 92 | + wnd.set_colormap(af.COLORMAP.HEAT) |
| 93 | + wnd[1, 1].image(disp_res, "Disparity Values") |
| 94 | + wnd.show() |
| 95 | + |
| 96 | + |
| 97 | +if __name__ == "__main__": |
| 98 | + if (len(sys.argv) > 1): |
| 99 | + af.set_device(int(sys.argv[1])) |
| 100 | + console = (sys.argv[2] == '-') if len(sys.argv) > 2 else False |
| 101 | + |
| 102 | + af.info() |
| 103 | + print("** ArrayFire template matching Demo **\n") |
| 104 | + templateMatchingDemo(console) |
| 105 | + |
0 commit comments