From fa90cf4450717c112c784151f011d81ade5f795c Mon Sep 17 00:00:00 2001 From: Lukas Kleybolte Date: Thu, 14 Oct 2021 14:41:09 +0200 Subject: [PATCH 1/8] add gabor_filter.py --- .../filters/gabor_filter.py | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 digital_image_processing/filters/gabor_filter.py diff --git a/digital_image_processing/filters/gabor_filter.py b/digital_image_processing/filters/gabor_filter.py new file mode 100644 index 000000000000..3d8825b1d5d5 --- /dev/null +++ b/digital_image_processing/filters/gabor_filter.py @@ -0,0 +1,55 @@ +# Implementation of the Gaborfilter +import numpy as np +from cv2 import imread, cvtColor, COLOR_BGR2GRAY, filter2D, CV_8UC3, imshow, waitKey + + +def gabor_filter_kernel(ksize, sigma, theta, lambd, gamma, psi): + # prepare kernel + gabor = np.zeros((ksize, ksize), dtype=np.float32) + + # each value + for y in range(ksize): + for x in range(ksize): + # distance from center + px = x - ksize // 2 + py = y - ksize // 2 + + # get kernel x + _x = np.cos(theta) * px + np.sin(theta) * py + + # get kernel y + _y = -np.sin(theta) * px + np.cos(theta) * py + + # fill kernel + gabor[y, x] = np.exp( + -(_x ** 2 + gamma ** 2 * _y ** 2) / (2 * sigma ** 2) + ) * np.cos(2 * np.pi * _x / lambd + psi) + + return gabor + + +if __name__ == "__main__": + # read original image + img = imread("../image_data/lena.jpg") + # turn image in gray scale value + gray = cvtColor(img, COLOR_BGR2GRAY) + + ksize = 10 + sigma = 8 + lambd = 10 + gamma = 0 + psi = 0 + + # Apply multiple Kernel to detect edges + out = np.zeros(gray.shape[:2]) + for theta in [0, 30, 60, 90, 120, 150]: + kernel_10 = gabor_filter_kernel(ksize, sigma, theta, lambd, gamma, psi) + out += filter2D(gray, CV_8UC3, kernel_10) + out = out / out.max() * 255 + out = out.astype(np.uint8) + + imshow("original", gray) + imshow("gabor filter with 20x20 mask and 6 directions", out) + + waitKey(0) +Mozartuss/Python \ No newline at end of file From ec3eed48930440a6c9819c7e449ef15f6adefeb9 Mon Sep 17 00:00:00 2001 From: Mozartus <32893711+Mozartuss@users.noreply.github.com> Date: Thu, 14 Oct 2021 14:47:07 +0200 Subject: [PATCH 2/8] Update gabor_filter.py --- digital_image_processing/filters/gabor_filter.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/digital_image_processing/filters/gabor_filter.py b/digital_image_processing/filters/gabor_filter.py index 3d8825b1d5d5..217cfc10c9fd 100644 --- a/digital_image_processing/filters/gabor_filter.py +++ b/digital_image_processing/filters/gabor_filter.py @@ -1,4 +1,5 @@ # Implementation of the Gaborfilter +# https://en.wikipedia.org/wiki/Gabor_filter import numpy as np from cv2 import imread, cvtColor, COLOR_BGR2GRAY, filter2D, CV_8UC3, imshow, waitKey @@ -52,4 +53,4 @@ def gabor_filter_kernel(ksize, sigma, theta, lambd, gamma, psi): imshow("gabor filter with 20x20 mask and 6 directions", out) waitKey(0) -Mozartuss/Python \ No newline at end of file +Mozartuss/Python From 82ab59406eed63d8cc3feae37ee95e1d2bea27ce Mon Sep 17 00:00:00 2001 From: Lukas Kleybolte Date: Thu, 14 Oct 2021 15:08:18 +0200 Subject: [PATCH 3/8] update gabor_filter.py --- .../filters/gabor_filter.py | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/digital_image_processing/filters/gabor_filter.py b/digital_image_processing/filters/gabor_filter.py index 217cfc10c9fd..a18593a545be 100644 --- a/digital_image_processing/filters/gabor_filter.py +++ b/digital_image_processing/filters/gabor_filter.py @@ -4,7 +4,20 @@ from cv2 import imread, cvtColor, COLOR_BGR2GRAY, filter2D, CV_8UC3, imshow, waitKey -def gabor_filter_kernel(ksize, sigma, theta, lambd, gamma, psi): +def gabor_filter_kernel( + ksize: int, sigma: int, theta: int, lambd: int, gamma: int, psi: int +) -> np.ndarray: + """ + :param ksize: The kernelsize of the convolutional filter (ksize x ksize) + :param sigma: standard deviation of the gaussian bell curve + :param theta: The orientation of the normal to the parallel stripes + of Gabor function. + :param lambd: Wavelength of the sinusoidal component. + :param gamma: The spatial aspect ratio and specifies the ellipticity + of the support of Gabor function. + :param psi: The phase offset of the sinusoidal function. + """ + # prepare kernel gabor = np.zeros((ksize, ksize), dtype=np.float32) @@ -35,16 +48,17 @@ def gabor_filter_kernel(ksize, sigma, theta, lambd, gamma, psi): # turn image in gray scale value gray = cvtColor(img, COLOR_BGR2GRAY) - ksize = 10 - sigma = 8 - lambd = 10 - gamma = 0 - psi = 0 - # Apply multiple Kernel to detect edges out = np.zeros(gray.shape[:2]) for theta in [0, 30, 60, 90, 120, 150]: - kernel_10 = gabor_filter_kernel(ksize, sigma, theta, lambd, gamma, psi) + """ + ksize = 10 + sigma = 8 + lambd = 10 + gamma = 0 + psi = 0 + """ + kernel_10 = gabor_filter_kernel(10, 8, theta, 10, 0, 0) out += filter2D(gray, CV_8UC3, kernel_10) out = out / out.max() * 255 out = out.astype(np.uint8) @@ -53,4 +67,3 @@ def gabor_filter_kernel(ksize, sigma, theta, lambd, gamma, psi): imshow("gabor filter with 20x20 mask and 6 directions", out) waitKey(0) -Mozartuss/Python From b198cd5dc88051238c3005ffcc420c61fe42e144 Mon Sep 17 00:00:00 2001 From: Lukas Kleybolte Date: Fri, 15 Oct 2021 17:37:49 +0200 Subject: [PATCH 4/8] add doctest --- digital_image_processing/filters/gabor_filter.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/digital_image_processing/filters/gabor_filter.py b/digital_image_processing/filters/gabor_filter.py index a18593a545be..b9e28eb6499d 100644 --- a/digital_image_processing/filters/gabor_filter.py +++ b/digital_image_processing/filters/gabor_filter.py @@ -16,6 +16,11 @@ def gabor_filter_kernel( :param gamma: The spatial aspect ratio and specifies the ellipticity of the support of Gabor function. :param psi: The phase offset of the sinusoidal function. + + >>> gabor_filter_kernel(3, 8, 0, 10, 0, 0).tolist() + [[0.8027212023735046, 1.0, 0.8027212023735046], [0.8027212023735046, 1.0, \ +0.8027212023735046], [0.8027212023735046, 1.0, 0.8027212023735046]] + """ # prepare kernel From 97bf960cfc86b9b1d2f14d97212ef3d5a14ca174 Mon Sep 17 00:00:00 2001 From: Lukas Kleybolte Date: Fri, 15 Oct 2021 17:42:25 +0200 Subject: [PATCH 5/8] change import order --- digital_image_processing/filters/gabor_filter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/digital_image_processing/filters/gabor_filter.py b/digital_image_processing/filters/gabor_filter.py index b9e28eb6499d..d77c7ef2c15d 100644 --- a/digital_image_processing/filters/gabor_filter.py +++ b/digital_image_processing/filters/gabor_filter.py @@ -1,7 +1,7 @@ # Implementation of the Gaborfilter # https://en.wikipedia.org/wiki/Gabor_filter import numpy as np -from cv2 import imread, cvtColor, COLOR_BGR2GRAY, filter2D, CV_8UC3, imshow, waitKey +from cv2 import COLOR_BGR2GRAY, CV_8UC3, cvtColor, filter2D, imread, imshow, waitKey def gabor_filter_kernel( From 08d703e1b27f68f3b751ea9264aad2f95333fdc6 Mon Sep 17 00:00:00 2001 From: Mozartus <32893711+Mozartuss@users.noreply.github.com> Date: Tue, 19 Oct 2021 15:06:05 +0200 Subject: [PATCH 6/8] Update digital_image_processing/filters/gabor_filter.py Co-authored-by: John Law --- digital_image_processing/filters/gabor_filter.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/digital_image_processing/filters/gabor_filter.py b/digital_image_processing/filters/gabor_filter.py index d77c7ef2c15d..f540a585d39a 100644 --- a/digital_image_processing/filters/gabor_filter.py +++ b/digital_image_processing/filters/gabor_filter.py @@ -48,6 +48,9 @@ def gabor_filter_kernel( if __name__ == "__main__": + import doctest + + doctest.testmod() # read original image img = imread("../image_data/lena.jpg") # turn image in gray scale value From ed0f359df2476164bdc26c3f8748389b6d158011 Mon Sep 17 00:00:00 2001 From: John Law Date: Wed, 27 Oct 2021 12:18:41 +0800 Subject: [PATCH 7/8] Update gabor_filter.py --- digital_image_processing/filters/gabor_filter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/digital_image_processing/filters/gabor_filter.py b/digital_image_processing/filters/gabor_filter.py index f540a585d39a..bfeb6abb1b4f 100644 --- a/digital_image_processing/filters/gabor_filter.py +++ b/digital_image_processing/filters/gabor_filter.py @@ -71,7 +71,7 @@ def gabor_filter_kernel( out = out / out.max() * 255 out = out.astype(np.uint8) - imshow("original", gray) - imshow("gabor filter with 20x20 mask and 6 directions", out) + imshow("Original", gray) + imshow("Gabor filter with 20x20 mask and 6 directions", out) waitKey(0) From 97dd0d45062c19593518eea99a158f788632a81f Mon Sep 17 00:00:00 2001 From: Lukas Kleybolte Date: Mon, 1 Nov 2021 23:39:23 +0100 Subject: [PATCH 8/8] fix gabor filter calculation --- digital_image_processing/filters/gabor_filter.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/digital_image_processing/filters/gabor_filter.py b/digital_image_processing/filters/gabor_filter.py index bfeb6abb1b4f..90aa049c24a0 100644 --- a/digital_image_processing/filters/gabor_filter.py +++ b/digital_image_processing/filters/gabor_filter.py @@ -24,6 +24,9 @@ def gabor_filter_kernel( """ # prepare kernel + # the kernel size have to be odd + if (ksize % 2) == 0: + ksize = ksize + 1 gabor = np.zeros((ksize, ksize), dtype=np.float32) # each value @@ -33,11 +36,16 @@ def gabor_filter_kernel( px = x - ksize // 2 py = y - ksize // 2 + # degree to radiant + _theta = theta / 180 * np.pi + cos_theta = np.cos(_theta) + sin_theta = np.sin(_theta) + # get kernel x - _x = np.cos(theta) * px + np.sin(theta) * py + _x = cos_theta * px + sin_theta * py # get kernel y - _y = -np.sin(theta) * px + np.cos(theta) * py + _y = -sin_theta * px + cos_theta * py # fill kernel gabor[y, x] = np.exp(