From d0c3057cbd00615869c97f21ca8bb88385b8d38a Mon Sep 17 00:00:00 2001 From: syurkevi Date: Thu, 30 Aug 2018 16:43:57 -0400 Subject: [PATCH 1/6] adds computer vision example --- examples/computer_vision/fast.py | 81 ++++++++++++++++++ examples/computer_vision/harris.py | 119 +++++++++++++++++++++++++++ examples/computer_vision/matching.py | 105 +++++++++++++++++++++++ examples/computer_vision/susan.py | 81 ++++++++++++++++++ 4 files changed, 386 insertions(+) create mode 100644 examples/computer_vision/fast.py create mode 100644 examples/computer_vision/harris.py create mode 100644 examples/computer_vision/matching.py create mode 100644 examples/computer_vision/susan.py diff --git a/examples/computer_vision/fast.py b/examples/computer_vision/fast.py new file mode 100644 index 000000000..f70193e5e --- /dev/null +++ b/examples/computer_vision/fast.py @@ -0,0 +1,81 @@ +#!/usr/bin/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 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 fast_demo(console): + + if console: + img_color = af.load_image("../../assets/examples/images/square.png", True); + else: + img_color = af.load_image("../../assets/examples/images/man.jpg", True); + + img_color /= 255.0 + img = af.color_space(img_color, af.CSPACE.GRAY, af.CSPACE.RGB) + + features = af.fast(img) + + xs = features.get_xpos() + ys = features.get_ypos() + + 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..bb89c3ac4 --- /dev/null +++ b/examples/computer_vision/harris.py @@ -0,0 +1,119 @@ +#!/usr/bin/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 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): + + if console: + img_color = af.load_image("../../assets/examples/images/square.png", True); + else: + img_color = af.load_image("../../assets/examples/images/man.jpg", True); + + img_color /= 255.0 + img = af.color_space(img_color, af.CSPACE.GRAY, af.CSPACE.RGB) + + 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, "FAST Feature Detector") + + while not wnd.close(): + wnd.image(img_color) + else: + idx = af.where(corners) + + corners_x = idx / corners.dims()[0] + corners_y = idx % 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..797781212 --- /dev/null +++ b/examples/computer_vision/matching.py @@ -0,0 +1,105 @@ +#!/usr/bin/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 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): + + if console: + img_color = af.load_image("../../assets/examples/images/square.png", True); + else: + img_color = af.load_image("../../assets/examples/images/man.jpg", 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..6211128d5 --- /dev/null +++ b/examples/computer_vision/susan.py @@ -0,0 +1,81 @@ +#!/usr/bin/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 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): + + if console: + img_color = af.load_image("../../assets/examples/images/square.png", True); + else: + img_color = af.load_image("../../assets/examples/images/man.jpg", True); + + img_color /= 255.0 + img = af.color_space(img_color, af.CSPACE.GRAY, af.CSPACE.RGB) + + features = af.susan(img) + + xs = features.get_xpos() + ys = features.get_ypos() + + 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, "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) + From 04398320de1b98904ab4da1457be559e7f5d39c9 Mon Sep 17 00:00:00 2001 From: syurkevi Date: Thu, 30 Aug 2018 17:04:20 -0400 Subject: [PATCH 2/6] image range updates fixing matching --- examples/computer_vision/fast.py | 10 +++++----- examples/computer_vision/harris.py | 6 +++--- examples/computer_vision/susan.py | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/computer_vision/fast.py b/examples/computer_vision/fast.py index f70193e5e..584ff6618 100644 --- a/examples/computer_vision/fast.py +++ b/examples/computer_vision/fast.py @@ -25,8 +25,8 @@ 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) - ymin = max(0, y - draw_len) - ymax = min(img.dims()[0], y + draw_len) + 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 @@ -40,13 +40,13 @@ def fast_demo(console): else: img_color = af.load_image("../../assets/examples/images/man.jpg", True); - img_color /= 255.0 img = af.color_space(img_color, af.CSPACE.GRAY, af.CSPACE.RGB) + img_color /= 255.0 features = af.fast(img) - xs = features.get_xpos() - ys = features.get_ypos() + xs = features.get_xpos().to_list() + ys = features.get_ypos().to_list() draw_len = 3; num_features = features.num_features().value diff --git a/examples/computer_vision/harris.py b/examples/computer_vision/harris.py index bb89c3ac4..1c8e53804 100644 --- a/examples/computer_vision/harris.py +++ b/examples/computer_vision/harris.py @@ -40,8 +40,8 @@ def harris_demo(console): else: img_color = af.load_image("../../assets/examples/images/man.jpg", True); - img_color /= 255.0 img = af.color_space(img_color, af.CSPACE.GRAY, af.CSPACE.RGB) + img_color /= 255.0 ix, iy = af.gradient(img) ixx = ix * ix @@ -100,8 +100,8 @@ def harris_demo(console): else: idx = af.where(corners) - corners_x = idx / corners.dims()[0] - corners_y = idx % corners.dims()[0] + corners_x = idx / float(corners.dims()[0]) + corners_y = idx % float(corners.dims()[0]) print(corners_x) print(corners_y) diff --git a/examples/computer_vision/susan.py b/examples/computer_vision/susan.py index 6211128d5..025001b49 100644 --- a/examples/computer_vision/susan.py +++ b/examples/computer_vision/susan.py @@ -40,13 +40,13 @@ def susan_demo(console): else: img_color = af.load_image("../../assets/examples/images/man.jpg", True); - img_color /= 255.0 img = af.color_space(img_color, af.CSPACE.GRAY, af.CSPACE.RGB) + img_color /= 255.0 features = af.susan(img) - xs = features.get_xpos() - ys = features.get_ypos() + xs = features.get_xpos().to_list() + ys = features.get_ypos().to_list() draw_len = 3; num_features = features.num_features().value From 6ecc9c05455127d14749527b9eb3bc3f3a387771 Mon Sep 17 00:00:00 2001 From: pradeep Date: Tue, 8 Sep 2020 10:39:16 +0530 Subject: [PATCH 3/6] Use os path util to fetch example path to determine assets location --- examples/computer_vision/fast.py | 8 ++++++-- examples/computer_vision/harris.py | 8 ++++++-- examples/computer_vision/matching.py | 8 ++++++-- examples/computer_vision/susan.py | 8 ++++++-- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/examples/computer_vision/fast.py b/examples/computer_vision/fast.py index 584ff6618..1091271c8 100644 --- a/examples/computer_vision/fast.py +++ b/examples/computer_vision/fast.py @@ -11,6 +11,7 @@ from time import time import arrayfire as af +import os import sys def draw_corners(img, x, y, draw_len): @@ -35,10 +36,13 @@ def draw_corners(img, x, y, draw_len): def fast_demo(console): + root_path = os.path.dirname(os.path.abspath(__file__)) + file_path = root_path if console: - img_color = af.load_image("../../assets/examples/images/square.png", True); + file_path += "/../../assets/examples/images/square.png" else: - img_color = af.load_image("../../assets/examples/images/man.jpg", True); + 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 diff --git a/examples/computer_vision/harris.py b/examples/computer_vision/harris.py index 1c8e53804..34659ebc3 100644 --- a/examples/computer_vision/harris.py +++ b/examples/computer_vision/harris.py @@ -11,6 +11,7 @@ from time import time import arrayfire as af +import os import sys def draw_corners(img, x, y, draw_len): @@ -35,10 +36,13 @@ def draw_corners(img, x, y, draw_len): def harris_demo(console): + root_path = os.path.dirname(os.path.abspath(__file__)) + file_path = root_path if console: - img_color = af.load_image("../../assets/examples/images/square.png", True); + file_path += "/../../assets/examples/images/square.png" else: - img_color = af.load_image("../../assets/examples/images/man.jpg", True); + 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 diff --git a/examples/computer_vision/matching.py b/examples/computer_vision/matching.py index 797781212..8bdeb4b78 100644 --- a/examples/computer_vision/matching.py +++ b/examples/computer_vision/matching.py @@ -11,6 +11,7 @@ from time import time import arrayfire as af +import os import sys def normalize(a): @@ -45,10 +46,13 @@ def draw_rectangle(img, x, y, wx, wy): def templateMatchingDemo(console): + root_path = os.path.dirname(os.path.abspath(__file__)) + file_path = root_path if console: - img_color = af.load_image("../../assets/examples/images/square.png", True); + file_path += "/../../assets/examples/images/square.png" else: - img_color = af.load_image("../../assets/examples/images/man.jpg", True); + 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) diff --git a/examples/computer_vision/susan.py b/examples/computer_vision/susan.py index 025001b49..8fb00c3bd 100644 --- a/examples/computer_vision/susan.py +++ b/examples/computer_vision/susan.py @@ -11,6 +11,7 @@ from time import time import arrayfire as af +import os import sys def draw_corners(img, x, y, draw_len): @@ -35,10 +36,13 @@ def draw_corners(img, x, y, draw_len): def susan_demo(console): + root_path = os.path.dirname(os.path.abspath(__file__)) + file_path = root_path if console: - img_color = af.load_image("../../assets/examples/images/square.png", True); + file_path += "/../../assets/examples/images/square.png" else: - img_color = af.load_image("../../assets/examples/images/man.jpg", True); + 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 From 0a1b318e236eb70f952c9374525a1cfcb14acc4c Mon Sep 17 00:00:00 2001 From: pradeep Date: Tue, 8 Sep 2020 10:39:41 +0530 Subject: [PATCH 4/6] Fix typo in harris detector example --- examples/computer_vision/harris.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/computer_vision/harris.py b/examples/computer_vision/harris.py index 34659ebc3..85388eea9 100644 --- a/examples/computer_vision/harris.py +++ b/examples/computer_vision/harris.py @@ -97,7 +97,7 @@ def harris_demo(console): print("Corners found: {}".format(good_corners)) if not console: # Previews color image with green crosshairs - wnd = af.Window(512, 512, "FAST Feature Detector") + wnd = af.Window(512, 512, "Harris Feature Detector") while not wnd.close(): wnd.image(img_color) From 84a3f1b970652946a3e6a20ef63a3f332eafb2cf Mon Sep 17 00:00:00 2001 From: pradeep Date: Tue, 8 Sep 2020 10:39:47 +0530 Subject: [PATCH 5/6] Workaround in susan example for swapped coordinates of features I believe this has to be fixed from upstream and then later fixed here. Added a TODO inside the example for the same --- examples/computer_vision/susan.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/computer_vision/susan.py b/examples/computer_vision/susan.py index 8fb00c3bd..4ae33fb09 100644 --- a/examples/computer_vision/susan.py +++ b/examples/computer_vision/susan.py @@ -59,7 +59,8 @@ def susan_demo(console): x = xs[f] y = ys[f] - img_color = draw_corners(img_color, x, y, draw_len) + # 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)) From ba6bdf3bb23e4b410f8c1442253a51f415ecd1b5 Mon Sep 17 00:00:00 2001 From: pradeep Date: Wed, 9 Sep 2020 13:09:47 +0530 Subject: [PATCH 6/6] Update python sheband in examples to widely adopted convention --- examples/computer_vision/fast.py | 2 +- examples/computer_vision/harris.py | 2 +- examples/computer_vision/matching.py | 2 +- examples/computer_vision/susan.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/computer_vision/fast.py b/examples/computer_vision/fast.py index 1091271c8..e3a1299e3 100644 --- a/examples/computer_vision/fast.py +++ b/examples/computer_vision/fast.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python ####################################################### # Copyright (c) 2018, ArrayFire diff --git a/examples/computer_vision/harris.py b/examples/computer_vision/harris.py index 85388eea9..27fd6c6f8 100644 --- a/examples/computer_vision/harris.py +++ b/examples/computer_vision/harris.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python ####################################################### # Copyright (c) 2018, ArrayFire diff --git a/examples/computer_vision/matching.py b/examples/computer_vision/matching.py index 8bdeb4b78..cab0cccdf 100644 --- a/examples/computer_vision/matching.py +++ b/examples/computer_vision/matching.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python ####################################################### # Copyright (c) 2018, ArrayFire diff --git a/examples/computer_vision/susan.py b/examples/computer_vision/susan.py index 4ae33fb09..37a5dbd11 100644 --- a/examples/computer_vision/susan.py +++ b/examples/computer_vision/susan.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python ####################################################### # Copyright (c) 2018, ArrayFire