From 414e9ec19c85c1c33e30cc982df48e56612dbc44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivana=20Kaji=C4=87?= Date: Sun, 31 Aug 2014 12:41:23 +0100 Subject: [PATCH 1/4] Added docu for gabor_filter. n_stds added to the parameter list. --- skimage/filters/_gabor.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/skimage/filters/_gabor.py b/skimage/filters/_gabor.py index b1f3fe3b..ff917edb 100644 --- a/skimage/filters/_gabor.py +++ b/skimage/filters/_gabor.py @@ -12,7 +12,7 @@ def _sigma_prefactor(bandwidth): return 1.0 / np.pi * np.sqrt(np.log(2)/2.0) * (2.0**b + 1) / (2.0**b - 1) -def gabor_kernel(frequency, theta=0, bandwidth=1, sigma_x=None, sigma_y=None, +def gabor_kernel(frequency, theta=0, bandwidth=1, sigma_x=None, sigma_y=None, n_stds=3, offset=0): """Return complex 2D Gabor filter kernel. @@ -34,6 +34,8 @@ def gabor_kernel(frequency, theta=0, bandwidth=1, sigma_x=None, sigma_y=None, Standard deviation in x- and y-directions. These directions apply to the kernel *before* rotation. If `theta = pi/2`, then the kernel is rotated 90 degrees so that `sigma_x` controls the *vertical* direction. + n_stds : int + Number of standard deviations until the array boundaries. offset : float, optional Phase offset of harmonic function in radians. @@ -47,13 +49,24 @@ def gabor_kernel(frequency, theta=0, bandwidth=1, sigma_x=None, sigma_y=None, .. [1] http://en.wikipedia.org/wiki/Gabor_filter .. [2] http://mplab.ucsd.edu/tutorials/gabor.pdf - """ + Examples + -------- + >>> from skimage.filter import gabor_kernel + >>> from skimage import io + + >>> gk = gabor_kernel(frequency=0.2) + >>> io.imshow(gk.real) # plot only the real part of the kernel + >>> io.show() + + >>> gk = gabor_kernel(frequency=0.2, bandwidth=0.1) # more ripples + >>> io.imshow(gk.real) + >>> io.show() + """ if sigma_x is None: sigma_x = _sigma_prefactor(bandwidth) / frequency if sigma_y is None: sigma_y = _sigma_prefactor(bandwidth) / frequency - n_stds = 3 x0 = np.ceil(max(np.abs(n_stds * sigma_x * np.cos(theta)), np.abs(n_stds * sigma_y * np.sin(theta)), 1)) y0 = np.ceil(max(np.abs(n_stds * sigma_y * np.cos(theta)), From e5cd943bc3ba3785955380cf5cc4e5fddfd66063 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivana=20Kaji=C4=87?= Date: Sun, 31 Aug 2014 13:46:57 +0100 Subject: [PATCH 2/4] Added examples for Gabor filters. --- skimage/filters/_gabor.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/skimage/filters/_gabor.py b/skimage/filters/_gabor.py index ff917edb..a8529c24 100644 --- a/skimage/filters/_gabor.py +++ b/skimage/filters/_gabor.py @@ -85,7 +85,7 @@ def gabor_kernel(frequency, theta=0, bandwidth=1, sigma_x=None, sigma_y=None, n_ def gabor_filter(image, frequency, theta=0, bandwidth=1, sigma_x=None, - sigma_y=None, offset=0, mode='reflect', cval=0): + sigma_y=None, n_stds=3, offset=0, mode='reflect', cval=0): """Return real and imaginary responses to Gabor filter. The real and imaginary parts of the Gabor filter kernel are applied to the @@ -97,7 +97,7 @@ def gabor_filter(image, frequency, theta=0, bandwidth=1, sigma_x=None, Parameters ---------- - image : array + image : 2-D array Input image. frequency : float Frequency of the harmonic function. @@ -111,6 +111,8 @@ def gabor_filter(image, frequency, theta=0, bandwidth=1, sigma_x=None, Standard deviation in x- and y-directions. These directions apply to the kernel *before* rotation. If `theta = pi/2`, then the kernel is rotated 90 degrees so that `sigma_x` controls the *vertical* direction. + n_stds : int + Number of standard deviations until the array boundaries. offset : float, optional Phase offset of harmonic function in radians. @@ -125,9 +127,18 @@ def gabor_filter(image, frequency, theta=0, bandwidth=1, sigma_x=None, .. [1] http://en.wikipedia.org/wiki/Gabor_filter .. [2] http://mplab.ucsd.edu/tutorials/gabor.pdf + Examples + -------- + >>> from skimage.filter import gabor_filter + >>> from skimage import data, io + + >>> image = data.checkerboard() + >>> filt_real, filt_imag = gabor_filter(image, 0.7) + >>> io.imshow(filt_real) + >>> io.show() """ assert_nD(image, 2) - g = gabor_kernel(frequency, theta, bandwidth, sigma_x, sigma_y, offset) + g = gabor_kernel(frequency, theta, bandwidth, sigma_x, sigma_y, n_stds, offset) filtered_real = ndimage.convolve(image, np.real(g), mode=mode, cval=cval) filtered_imag = ndimage.convolve(image, np.imag(g), mode=mode, cval=cval) From 2c830a34e20c31602fc41ca2eb11b11503e0832f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivana=20Kaji=C4=87?= Date: Sun, 31 Aug 2014 14:51:21 +0100 Subject: [PATCH 3/4] Updated Return section. --- skimage/filters/_gabor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/filters/_gabor.py b/skimage/filters/_gabor.py index a8529c24..09d84c3d 100644 --- a/skimage/filters/_gabor.py +++ b/skimage/filters/_gabor.py @@ -120,7 +120,7 @@ def gabor_filter(image, frequency, theta=0, bandwidth=1, sigma_x=None, ------- real, imag : arrays Filtered images using the real and imaginary parts of the Gabor filter - kernel. + kernel. Images are of the same dimensions as the input one. References ---------- From 98f41fb12b0117bbb1f566ae38957ef6cb08c65d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivana=20Kaji=C4=87?= Date: Sun, 31 Aug 2014 15:40:42 +0100 Subject: [PATCH 4/4] More detailed docu. Modified examples. Added doctest skipping of matplotlib's commands. --- CONTRIBUTORS.txt | 3 ++ skimage/filters/_gabor.py | 90 +++++++++++++++++++++++++-------------- 2 files changed, 62 insertions(+), 31 deletions(-) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index ec9798aa..cc8ddd1d 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -194,3 +194,6 @@ - Alexey Umnov skimage.draw.ellipse bug fix and tests. + +- Ivana Kajic + Updated description and examples in documentation for gabor filters diff --git a/skimage/filters/_gabor.py b/skimage/filters/_gabor.py index 09d84c3d..657ff7e3 100644 --- a/skimage/filters/_gabor.py +++ b/skimage/filters/_gabor.py @@ -12,30 +12,34 @@ def _sigma_prefactor(bandwidth): return 1.0 / np.pi * np.sqrt(np.log(2)/2.0) * (2.0**b + 1) / (2.0**b - 1) -def gabor_kernel(frequency, theta=0, bandwidth=1, sigma_x=None, sigma_y=None, n_stds=3, - offset=0): +def gabor_kernel(frequency, theta=0, bandwidth=1, sigma_x=None, sigma_y=None, + n_stds=3, offset=0): """Return complex 2D Gabor filter kernel. - Frequency and orientation representations of the Gabor filter are similar - to those of the human visual system. It is especially suitable for texture - classification using Gabor filter banks. + Gabor kernel is a Gaussian kernel modulated by a complex harmonic function. + Harmonic function consists of an imaginary sine function and a real + cosine function. Spatial frequency is inversely proportional to the + wavelength of the harmonic and to the standard deviation of a Gaussian + kernel. The bandwidth is also inversely proportional to the standard + deviation. Parameters ---------- frequency : float - Frequency of the harmonic function. - theta : float + Spatial frequency of the harmonic function. Specified in pixels. + theta : float, optional Orientation in radians. If 0, the harmonic is in the x-direction. - bandwidth : float + bandwidth : float, optional The bandwidth captured by the filter. For fixed bandwidth, `sigma_x` and `sigma_y` will decrease with increasing frequency. This value is ignored if `sigma_x` and `sigma_y` are set by the user. - sigma_x, sigma_y : float + sigma_x, sigma_y : float, optional Standard deviation in x- and y-directions. These directions apply to the kernel *before* rotation. If `theta = pi/2`, then the kernel is rotated 90 degrees so that `sigma_x` controls the *vertical* direction. - n_stds : int - Number of standard deviations until the array boundaries. + n_stds : scalar, optional + The linear size of the kernel is n_stds (3 by default) standard + deviations offset : float, optional Phase offset of harmonic function in radians. @@ -53,15 +57,20 @@ def gabor_kernel(frequency, theta=0, bandwidth=1, sigma_x=None, sigma_y=None, n_ -------- >>> from skimage.filter import gabor_kernel >>> from skimage import io + >>> from matplotlib import pyplot as plt # doctest: +SKIP >>> gk = gabor_kernel(frequency=0.2) - >>> io.imshow(gk.real) # plot only the real part of the kernel - >>> io.show() + >>> plt.figure() # doctest: +SKIP + >>> io.imshow(gk.real) # doctest: +SKIP + >>> io.show() # doctest: +SKIP - >>> gk = gabor_kernel(frequency=0.2, bandwidth=0.1) # more ripples - >>> io.imshow(gk.real) - >>> io.show() - """ + >>> # more ripples (equivalent to increasing the size of the + >>> # Gaussian spread) + >>> gk = gabor_kernel(frequency=0.2, bandwidth=0.1) + >>> plt.figure() # doctest: +SKIP + >>> io.imshow(gk.real) # doctest: +SKIP + >>> io.show() # doctest: +SKIP + """ if sigma_x is None: sigma_x = _sigma_prefactor(bandwidth) / frequency if sigma_y is None: @@ -91,30 +100,39 @@ def gabor_filter(image, frequency, theta=0, bandwidth=1, sigma_x=None, The real and imaginary parts of the Gabor filter kernel are applied to the image and the response is returned as a pair of arrays. - Frequency and orientation representations of the Gabor filter are similar - to those of the human visual system. It is especially suitable for texture - classification using Gabor filter banks. + Gabor filter is a linear filter with a Gaussian kernel which is modulated + by a sinusoidal plane wave. Frequency and orientation representations of + the Gabor filter are similar to those of the human visual system. + Gabor filter banks are commonly used in computer vision and image + processing. They are especially suitable for edge detection and texture + classification. Parameters ---------- image : 2-D array Input image. frequency : float - Frequency of the harmonic function. - theta : float + Spatial frequency of the harmonic function. Specified in pixels. + theta : float, optional Orientation in radians. If 0, the harmonic is in the x-direction. - bandwidth : float + bandwidth : float, optional The bandwidth captured by the filter. For fixed bandwidth, `sigma_x` and `sigma_y` will decrease with increasing frequency. This value is ignored if `sigma_x` and `sigma_y` are set by the user. - sigma_x, sigma_y : float + sigma_x, sigma_y : float, optional Standard deviation in x- and y-directions. These directions apply to the kernel *before* rotation. If `theta = pi/2`, then the kernel is rotated 90 degrees so that `sigma_x` controls the *vertical* direction. - n_stds : int - Number of standard deviations until the array boundaries. + n_stds : scalar, optional + The linear size of the kernel is n_stds (3 by default) standard + deviations. offset : float, optional Phase offset of harmonic function in radians. + mode : string, optional + Mode used to convolve image with a kernel, passed to `ndimage.convolve` + cval : scalar, optional + Value to fill past edges of input if `mode` of convolution is + 'constant'. The parameter is passed to `ndimage.convolve`. Returns ------- @@ -131,14 +149,24 @@ def gabor_filter(image, frequency, theta=0, bandwidth=1, sigma_x=None, -------- >>> from skimage.filter import gabor_filter >>> from skimage import data, io + >>> from matplotlib import pyplot as plt # doctest: +SKIP - >>> image = data.checkerboard() - >>> filt_real, filt_imag = gabor_filter(image, 0.7) - >>> io.imshow(filt_real) - >>> io.show() + >>> image = data.coins() + >>> # detecting edges in a coin image + >>> filt_real, filt_imag = gabor_filter(image, frequency=0.6) + >>> plt.figure() # doctest: +SKIP + >>> io.imshow(filt_real) # doctest: +SKIP + >>> io.show() # doctest: +SKIP + + >>> # less sensitivity to finer details with the lower frequency kernel + >>> filt_real, filt_imag = gabor_filter(image, frequency=0.1) + >>> plt.figure() # doctest: +SKIP + >>> io.imshow(filt_real) # doctest: +SKIP + >>> io.show() # doctest: +SKIP """ assert_nD(image, 2) - g = gabor_kernel(frequency, theta, bandwidth, sigma_x, sigma_y, n_stds, offset) + g = gabor_kernel(frequency, theta, bandwidth, sigma_x, sigma_y, n_stds, + offset) filtered_real = ndimage.convolve(image, np.real(g), mode=mode, cval=cval) filtered_imag = ndimage.convolve(image, np.imag(g), mode=mode, cval=cval)