diff --git a/examples/computer_vision/fast.py b/examples/computer_vision/fast.py new file mode 100644 index 000000000..e3a1299e3 --- /dev/null +++ b/examples/computer_vision/fast.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python + +####################################################### +# Copyright (c) 2018, ArrayFire +# All rights reserved. +# +# This file is distributed under 3-clause BSD license. +# The complete license agreement can be obtained at: +# http://arrayfire.com/licenses/BSD-3-Clause +######################################################## + +from time import time +import arrayfire as af +import os +import sys + +def draw_corners(img, x, y, draw_len): + # Draw vertical line of (draw_len * 2 + 1) pixels centered on the corner + # Set only the first channel to 1 (green lines) + xmin = max(0, x - draw_len) + xmax = min(img.dims()[1], x + draw_len) + + img[y, xmin : xmax, 0] = 0.0 + img[y, xmin : xmax, 1] = 1.0 + img[y, xmin : xmax, 2] = 0.0 + + # Draw vertical line of (draw_len * 2 + 1) pixels centered on the corner + # Set only the first channel to 1 (green lines) + ymin = int(max(0, y - draw_len)) + ymax = int(min(img.dims()[0], y + draw_len)) + + img[ymin : ymax, x, 0] = 0.0 + img[ymin : ymax, x, 1] = 1.0 + img[ymin : ymax, x, 2] = 0.0 + return img + +def fast_demo(console): + + root_path = os.path.dirname(os.path.abspath(__file__)) + file_path = root_path + if console: + file_path += "/../../assets/examples/images/square.png" + else: + file_path += "/../../assets/examples/images/man.jpg" + img_color = af.load_image(file_path, True); + + img = af.color_space(img_color, af.CSPACE.GRAY, af.CSPACE.RGB) + img_color /= 255.0 + + features = af.fast(img) + + xs = features.get_xpos().to_list() + ys = features.get_ypos().to_list() + + draw_len = 3; + num_features = features.num_features().value + for f in range(num_features): + print(f) + x = xs[f] + y = ys[f] + + img_color = draw_corners(img_color, x, y, draw_len) + + + print("Features found: {}".format(num_features)) + if not console: + # Previews color image with green crosshairs + wnd = af.Window(512, 512, "FAST Feature Detector") + + while not wnd.close(): + wnd.image(img_color) + else: + print(xs); + print(ys); + + +if __name__ == "__main__": + if (len(sys.argv) > 1): + af.set_device(int(sys.argv[1])) + console = (sys.argv[2] == '-') if len(sys.argv) > 2 else False + + af.info() + print("** ArrayFire FAST Feature Detector Demo **\n") + fast_demo(console) + diff --git a/examples/computer_vision/harris.py b/examples/computer_vision/harris.py new file mode 100644 index 000000000..27fd6c6f8 --- /dev/null +++ b/examples/computer_vision/harris.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python + +####################################################### +# Copyright (c) 2018, ArrayFire +# All rights reserved. +# +# This file is distributed under 3-clause BSD license. +# The complete license agreement can be obtained at: +# http://arrayfire.com/licenses/BSD-3-Clause +######################################################## + +from time import time +import arrayfire as af +import os +import sys + +def draw_corners(img, x, y, draw_len): + # Draw vertical line of (draw_len * 2 + 1) pixels centered on the corner + # Set only the first channel to 1 (green lines) + xmin = max(0, x - draw_len) + xmax = min(img.dims()[1], x + draw_len) + + img[y, xmin : xmax, 0] = 0.0 + img[y, xmin : xmax, 1] = 1.0 + img[y, xmin : xmax, 2] = 0.0 + + # Draw vertical line of (draw_len * 2 + 1) pixels centered on the corner + # Set only the first channel to 1 (green lines) + ymin = max(0, y - draw_len) + ymax = min(img.dims()[0], y + draw_len) + + img[ymin : ymax, x, 0] = 0.0 + img[ymin : ymax, x, 1] = 1.0 + img[ymin : ymax, x, 2] = 0.0 + return img + +def harris_demo(console): + + root_path = os.path.dirname(os.path.abspath(__file__)) + file_path = root_path + if console: + file_path += "/../../assets/examples/images/square.png" + else: + file_path += "/../../assets/examples/images/man.jpg" + img_color = af.load_image(file_path, True); + + img = af.color_space(img_color, af.CSPACE.GRAY, af.CSPACE.RGB) + img_color /= 255.0 + + ix, iy = af.gradient(img) + ixx = ix * ix + ixy = ix * iy + iyy = iy * iy + + # Compute a Gaussian kernel with standard deviation of 1.0 and length of 5 pixels + # These values can be changed to use a smaller or larger window + gauss_filt = af.gaussian_kernel(5, 5, 1.0, 1.0) + + # Filter second order derivatives + ixx = af.convolve(ixx, gauss_filt) + ixy = af.convolve(ixy, gauss_filt) + iyy = af.convolve(iyy, gauss_filt) + + # Calculate trace + itr = ixx + iyy + + # Calculate determinant + idet = ixx * iyy - ixy * ixy + + # Calculate Harris response + response = idet - 0.04 * (itr * itr) + + # Get maximum response for each 3x3 neighborhood + mask = af.constant(1, 3, 3) + max_resp = af.dilate(response, mask) + + # Discard responses that are not greater than threshold + corners = response > 1e5 + corners = corners * response + + # Discard responses that are not equal to maximum neighborhood response, + # scale them to original value + corners = (corners == max_resp) * corners + + # Copy device array to python list on host + corners_list = corners.to_list() + + draw_len = 3 + good_corners = 0 + for x in range(img_color.dims()[1]): + for y in range(img_color.dims()[0]): + if corners_list[x][y] > 1e5: + img_color = draw_corners(img_color, x, y, draw_len) + good_corners += 1 + + + print("Corners found: {}".format(good_corners)) + if not console: + # Previews color image with green crosshairs + wnd = af.Window(512, 512, "Harris Feature Detector") + + while not wnd.close(): + wnd.image(img_color) + else: + idx = af.where(corners) + + corners_x = idx / float(corners.dims()[0]) + corners_y = idx % float(corners.dims()[0]) + + print(corners_x) + print(corners_y) + + +if __name__ == "__main__": + if (len(sys.argv) > 1): + af.set_device(int(sys.argv[1])) + console = (sys.argv[2] == '-') if len(sys.argv) > 2 else False + + af.info() + print("** ArrayFire Harris Corner Detector Demo **\n") + + harris_demo(console) + diff --git a/examples/computer_vision/matching.py b/examples/computer_vision/matching.py new file mode 100644 index 000000000..cab0cccdf --- /dev/null +++ b/examples/computer_vision/matching.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python + +####################################################### +# Copyright (c) 2018, ArrayFire +# All rights reserved. +# +# This file is distributed under 3-clause BSD license. +# The complete license agreement can be obtained at: +# http://arrayfire.com/licenses/BSD-3-Clause +######################################################## + +from time import time +import arrayfire as af +import os +import sys + +def normalize(a): + max_ = float(af.max(a)) + min_ = float(af.min(a)) + return (a - min_) / (max_ - min_) + +def draw_rectangle(img, x, y, wx, wy): + print("\nMatching patch origin = ({}, {})\n".format(x, y)) + + # top edge + img[y, x : x + wx, 0] = 0.0 + img[y, x : x + wx, 1] = 0.0 + img[y, x : x + wx, 2] = 1.0 + + # bottom edge + img[y + wy, x : x + wx, 0] = 0.0 + img[y + wy, x : x + wx, 1] = 0.0 + img[y + wy, x : x + wx, 2] = 1.0 + + # left edge + img[y : y + wy, x, 0] = 0.0 + img[y : y + wy, x, 1] = 0.0 + img[y : y + wy, x, 2] = 1.0 + + # left edge + img[y : y + wy, x + wx, 0] = 0.0 + img[y : y + wy, x + wx, 1] = 0.0 + img[y : y + wy, x + wx, 2] = 1.0 + + return img + +def templateMatchingDemo(console): + + root_path = os.path.dirname(os.path.abspath(__file__)) + file_path = root_path + if console: + file_path += "/../../assets/examples/images/square.png" + else: + file_path += "/../../assets/examples/images/man.jpg" + img_color = af.load_image(file_path, True); + + # Convert the image from RGB to gray-scale + img = af.color_space(img_color, af.CSPACE.GRAY, af.CSPACE.RGB) + iDims = img.dims() + print("Input image dimensions: ", iDims) + + # Extract a patch from the input image + patch_size = 100 + tmp_img = img[100 : 100+patch_size, 100 : 100+patch_size] + + result = af.match_template(img, tmp_img) # Default disparity metric is + # Sum of Absolute differences (SAD) + # Currently supported metrics are + # AF_SAD, AF_ZSAD, AF_LSAD, AF_SSD, + # AF_ZSSD, AF_LSSD + + disp_img = img / 255.0 + disp_tmp = tmp_img / 255.0 + disp_res = normalize(result) + + minval, minloc = af.imin(disp_res) + print("Location(linear index) of minimum disparity value = {}".format(minloc)) + + if not console: + marked_res = af.tile(disp_img, 1, 1, 3) + marked_res = draw_rectangle(marked_res, minloc%iDims[0], minloc/iDims[0],\ + patch_size, patch_size) + + print("Note: Based on the disparity metric option provided to matchTemplate function") + print("either minimum or maximum disparity location is the starting corner") + print("of our best matching patch to template image in the search image") + + wnd = af.Window(512, 512, "Template Matching Demo") + + while not wnd.close(): + wnd.set_colormap(af.COLORMAP.DEFAULT) + wnd.grid(2, 2) + wnd[0, 0].image(disp_img, "Search Image" ) + wnd[0, 1].image(disp_tmp, "Template Patch" ) + wnd[1, 0].image(marked_res, "Best Match" ) + wnd.set_colormap(af.COLORMAP.HEAT) + wnd[1, 1].image(disp_res, "Disparity Values") + wnd.show() + + +if __name__ == "__main__": + if (len(sys.argv) > 1): + af.set_device(int(sys.argv[1])) + console = (sys.argv[2] == '-') if len(sys.argv) > 2 else False + + af.info() + print("** ArrayFire template matching Demo **\n") + templateMatchingDemo(console) + diff --git a/examples/computer_vision/susan.py b/examples/computer_vision/susan.py new file mode 100644 index 000000000..37a5dbd11 --- /dev/null +++ b/examples/computer_vision/susan.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python + +####################################################### +# Copyright (c) 2018, ArrayFire +# All rights reserved. +# +# This file is distributed under 3-clause BSD license. +# The complete license agreement can be obtained at: +# http://arrayfire.com/licenses/BSD-3-Clause +######################################################## + +from time import time +import arrayfire as af +import os +import sys + +def draw_corners(img, x, y, draw_len): + # Draw vertical line of (draw_len * 2 + 1) pixels centered on the corner + # Set only the first channel to 1 (green lines) + xmin = max(0, x - draw_len) + xmax = min(img.dims()[1], x + draw_len) + + img[y, xmin : xmax, 0] = 0.0 + img[y, xmin : xmax, 1] = 1.0 + img[y, xmin : xmax, 2] = 0.0 + + # Draw vertical line of (draw_len * 2 + 1) pixels centered on the corner + # Set only the first channel to 1 (green lines) + ymin = max(0, y - draw_len) + ymax = min(img.dims()[0], y + draw_len) + + img[ymin : ymax, x, 0] = 0.0 + img[ymin : ymax, x, 1] = 1.0 + img[ymin : ymax, x, 2] = 0.0 + return img + +def susan_demo(console): + + root_path = os.path.dirname(os.path.abspath(__file__)) + file_path = root_path + if console: + file_path += "/../../assets/examples/images/square.png" + else: + file_path += "/../../assets/examples/images/man.jpg" + img_color = af.load_image(file_path, True); + + img = af.color_space(img_color, af.CSPACE.GRAY, af.CSPACE.RGB) + img_color /= 255.0 + + features = af.susan(img) + + xs = features.get_xpos().to_list() + ys = features.get_ypos().to_list() + + draw_len = 3; + num_features = features.num_features().value + for f in range(num_features): + print(f) + x = xs[f] + y = ys[f] + + # TODO fix coord order to x,y after upstream fix + img_color = draw_corners(img_color, y, x, draw_len) + + + print("Features found: {}".format(num_features)) + if not console: + # Previews color image with green crosshairs + wnd = af.Window(512, 512, "SUSAN Feature Detector") + + while not wnd.close(): + wnd.image(img_color) + else: + print(xs); + print(ys); + + +if __name__ == "__main__": + if (len(sys.argv) > 1): + af.set_device(int(sys.argv[1])) + console = (sys.argv[2] == '-') if len(sys.argv) > 2 else False + + af.info() + print("** ArrayFire SUSAN Feature Detector Demo **\n") + susan_demo(console) +