|
| 1 | +# Implementation of the Gaborfilter |
| 2 | +# https://en.wikipedia.org/wiki/Gabor_filter |
| 3 | +import numpy as np |
| 4 | +from cv2 import COLOR_BGR2GRAY, CV_8UC3, cvtColor, filter2D, imread, imshow, waitKey |
| 5 | + |
| 6 | + |
| 7 | +def gabor_filter_kernel( |
| 8 | + ksize: int, sigma: int, theta: int, lambd: int, gamma: int, psi: int |
| 9 | +) -> np.ndarray: |
| 10 | + """ |
| 11 | + :param ksize: The kernelsize of the convolutional filter (ksize x ksize) |
| 12 | + :param sigma: standard deviation of the gaussian bell curve |
| 13 | + :param theta: The orientation of the normal to the parallel stripes |
| 14 | + of Gabor function. |
| 15 | + :param lambd: Wavelength of the sinusoidal component. |
| 16 | + :param gamma: The spatial aspect ratio and specifies the ellipticity |
| 17 | + of the support of Gabor function. |
| 18 | + :param psi: The phase offset of the sinusoidal function. |
| 19 | +
|
| 20 | + >>> gabor_filter_kernel(3, 8, 0, 10, 0, 0).tolist() |
| 21 | + [[0.8027212023735046, 1.0, 0.8027212023735046], [0.8027212023735046, 1.0, \ |
| 22 | +0.8027212023735046], [0.8027212023735046, 1.0, 0.8027212023735046]] |
| 23 | +
|
| 24 | + """ |
| 25 | + |
| 26 | + # prepare kernel |
| 27 | + # the kernel size have to be odd |
| 28 | + if (ksize % 2) == 0: |
| 29 | + ksize = ksize + 1 |
| 30 | + gabor = np.zeros((ksize, ksize), dtype=np.float32) |
| 31 | + |
| 32 | + # each value |
| 33 | + for y in range(ksize): |
| 34 | + for x in range(ksize): |
| 35 | + # distance from center |
| 36 | + px = x - ksize // 2 |
| 37 | + py = y - ksize // 2 |
| 38 | + |
| 39 | + # degree to radiant |
| 40 | + _theta = theta / 180 * np.pi |
| 41 | + cos_theta = np.cos(_theta) |
| 42 | + sin_theta = np.sin(_theta) |
| 43 | + |
| 44 | + # get kernel x |
| 45 | + _x = cos_theta * px + sin_theta * py |
| 46 | + |
| 47 | + # get kernel y |
| 48 | + _y = -sin_theta * px + cos_theta * py |
| 49 | + |
| 50 | + # fill kernel |
| 51 | + gabor[y, x] = np.exp( |
| 52 | + -(_x ** 2 + gamma ** 2 * _y ** 2) / (2 * sigma ** 2) |
| 53 | + ) * np.cos(2 * np.pi * _x / lambd + psi) |
| 54 | + |
| 55 | + return gabor |
| 56 | + |
| 57 | + |
| 58 | +if __name__ == "__main__": |
| 59 | + import doctest |
| 60 | + |
| 61 | + doctest.testmod() |
| 62 | + # read original image |
| 63 | + img = imread("../image_data/lena.jpg") |
| 64 | + # turn image in gray scale value |
| 65 | + gray = cvtColor(img, COLOR_BGR2GRAY) |
| 66 | + |
| 67 | + # Apply multiple Kernel to detect edges |
| 68 | + out = np.zeros(gray.shape[:2]) |
| 69 | + for theta in [0, 30, 60, 90, 120, 150]: |
| 70 | + """ |
| 71 | + ksize = 10 |
| 72 | + sigma = 8 |
| 73 | + lambd = 10 |
| 74 | + gamma = 0 |
| 75 | + psi = 0 |
| 76 | + """ |
| 77 | + kernel_10 = gabor_filter_kernel(10, 8, theta, 10, 0, 0) |
| 78 | + out += filter2D(gray, CV_8UC3, kernel_10) |
| 79 | + out = out / out.max() * 255 |
| 80 | + out = out.astype(np.uint8) |
| 81 | + |
| 82 | + imshow("Original", gray) |
| 83 | + imshow("Gabor filter with 20x20 mask and 6 directions", out) |
| 84 | + |
| 85 | + waitKey(0) |
0 commit comments