 Vivek Kumar

# Multi-dimensional Image Processing Using SciPy

• May 9, 2019
• 610 Views
• May 9, 2019
• 610 Views
Data
SciPy

## Introduction

In this guide, you will learn about various image processing and analysis methods provided by SciPy. So far, we have introduced you with SciPy's Linear Algebra, Stats, and Optimization Sub-packages. In this guide, we are going to focus on another SciPy subpackage named `ndimage`.

By the end of this guide, you will be able to implement various filter methods available inside SciPy.

## The Baseline

Throughout this guide, we will be using the following libraries:

``````1
2
3
4
5
6
``````# Importing necessary libraries
import numpy as np
import scipy as sp
from scipy import ndimage
from scipy import misc
import matplotlib.pyplot as plt``````
python

## Filter Functions

In this section, we're going to discuss the implementation of given filter categories:

1. Smoothing filters
2. Filters based on order statistics
3. Derivatives

### 1. Smoothing Filters

SciPy provides four smoothing filter methods namely:

• gaussian_filter1d: Implements a one-dimensional Gaussian filter. Here, the parameter `sigma` controls the standard-deviation of the Gaussian filter. An `order` of 0 would perform convolution with a Gaussian kernel, whereas, an `order` of 1, 2, or 3 would convolve with first, second, and third derivatives of a Gaussian.

• gaussian_filter: This method implements a multidimensional Gaussian filter. Here, parameter sigma accepts a sequence of standard-deviation along each axis. In case if a sequence is not passed rather a single number then the standard deviation is assumed to be equal in all directions.

• uniform_filter1d: This method calculates a one-dimensional uniform filter of the given `size` along the given axis.

• uniform_filter: This method implements a multi-dimensional filter. This method also follows a similar concept as `gaussian_filter` method where the size of the uniform filter is given for each axis in the form of a sequence of numbers via the `size` parameter. However, if no sequence is passed, but a single number is passed instead, then the sizes along all the axis are considered equal.

Here, we show the implementation of these filters:

``````1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
``````# ====================
# 1. gaussian_filter1d
# ====================
ndimage.gaussian_filter1d(np.arange(5, dtype=np.float64), sigma=1)

# Output:
# array([0.42704095, 1.06782203, 2.        , 2.93217797, 3.57295905])

ndimage.gaussian_filter1d(np.arange(5, dtype=np.float64), sigma=3)

# Output:
# array([1.67938648, 1.80184558, 2.        , 2.19815442, 2.32061352])

np.random.seed(42)
x = np.random.randn(101).cumsum()
y3 = ndimage.gaussian_filter1d(x, sigma=3)
y6 = ndimage.gaussian_filter1d(x, sigma=6)

plt.figure(figsize=(8, 5))
plt.plot(x, 'k', label='original data')
plt.plot(y3, '--', label='filtered, sigma=3')
plt.plot(y6, ':', label='filtered, sigma=6')
plt.legend()
plt.grid()
plt.show()``````
python ``````1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
``````# ==================
# 2. gaussian_filter
# ==================

mat = np.arange(100, step=4).reshape((5,5))
mat

# Output:
# array([[ 0,  4,  8, 12, 16],
#        [20, 24, 28, 32, 36],
#        [40, 44, 48, 52, 56],
#        [60, 64, 68, 72, 76],
#        [80, 84, 88, 92, 96]])

ndimage.gaussian_filter(mat, sigma=1)

# Output:
# array([[ 9, 12, 16, 19, 22],
#        [22, 25, 29, 32, 35],
#        [41, 44, 48, 51, 54],
#        [59, 62, 66, 69, 72],
#        [72, 75, 79, 82, 85]])

ndimage.gaussian_filter(mat, sigma=2)

# Output:
# array([[26, 27, 30, 32, 33],
#        [33, 34, 37, 39, 40],
#        [44, 45, 48, 50, 51],
#        [54, 55, 58, 60, 61],
#        [61, 62, 65, 67, 68]])

fig = plt.figure(figsize=(12, 8))
ax1 = fig.add_subplot(121)  # First subplot
ax2 = fig.add_subplot(122)  # Second subplot
ascent = misc.ascent()
result = ndimage.gaussian_filter(ascent, sigma=5)
ax1.imshow(ascent)
ax2.imshow(result)
plt.show()``````
python ``````1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
``````# ===================
# 3. uniform_filter1d
# ===================
ndimage.uniform_filter1d(np.arange(10), size=3)

# Output:
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 8])

np.random.seed(42)
x = np.random.randn(101).cumsum()
y3 = ndimage.uniform_filter1d(x, size=3)
y10 = ndimage.uniform_filter1d(x, size=10)

plt.figure(figsize=(8, 5))
plt.plot(x, 'k', label='original data')
plt.plot(y3, '--', label='filtered, size=3')
plt.plot(y10, ':', label='filtered, size=10')
plt.legend()
plt.grid()
plt.show()``````
python ``````1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
``````# =================
# 4. uniform_filter
# =================
mat = np.arange(100, step=4).reshape((5,5))
mat

# Output:
# array([[ 0,  4,  8, 12, 16],
#        [20, 24, 28, 32, 36],
#        [40, 44, 48, 52, 56],
#        [60, 64, 68, 72, 76],
#        [80, 84, 88, 92, 96]])

ndimage.uniform_filter(mat, size=3)

# Output:
# array([[ 7, 10, 14, 18, 20],
#        [21, 24, 28, 32, 34],
#        [41, 44, 48, 52, 54],
#        [61, 64, 68, 72, 74],
#        [74, 77, 81, 85, 87]])

fig = plt.figure(figsize=(12, 8))
ax1 = fig.add_subplot(121)  # First subplot
ax2 = fig.add_subplot(122)  # Second subplot
ascent = misc.ascent()
result = ndimage.uniform_filter(ascent, size=7)
ax1.imshow(ascent)
ax2.imshow(result)
plt.show()``````
python ### 2. Filters Based on Order Statistics

There are seven filters provided by SciPy based on order statistics:

• minimum_filter1d: This method calculates a one-dimensional minimum filter of a given size on a given axis.

• maximum_filter1d: This method calculates a one-dimensional maximum filter of a given size on a given axis.

• minimum_filter: This method calculates a multi-dimensional minimum filter.

• maximum_filter: This method calculates a multi-dimensional maximum filter.

• rank_filter: This method calculates a multi-dimensional rank filter.

• percentile_filter: This method calculates a multi-dimensional percentile filter.

• median_filter: This method calculates a multi-dimensional median filter.

Here's an implementation of these filters in python:

``````1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
``````# ===================
# 1. minimum_filter1d
# ===================

np.random.seed(42)
x = np.random.randn(101).cumsum()
y3 = ndimage.minimum_filter1d(x, size=3)
y10 = ndimage.minimum_filter1d(x, size=10)
plt.figure(figsize=(8, 5))
plt.plot(x, 'k', label='original data')
plt.plot(y3, '--', label='filtered, size=3')
plt.plot(y10, ':', label='filtered, size=10')
plt.legend()
plt.grid()
plt.show()``````
python ``````1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
``````# ===================
# 2. maximum_filter1d
# ===================

np.random.seed(42)
x = np.random.randn(101).cumsum()
y3 = ndimage.maximum_filter1d(x, size=3)
y10 = ndimage.maximum_filter1d(x, size=10)
plt.figure(figsize=(8, 5))
plt.plot(x, 'k', label='original data')
plt.plot(y3, '--', label='filtered, size=3')
plt.plot(y10, ':', label='filtered, size=10')
plt.legend()
plt.grid()
plt.show()``````
python ``````1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
``````# ============================================
# minimum_filter, maximum_filter, rank_filter
# percentile_filter, median_filter
# ============================================

fig = plt.figure(figsize=(15, 15))
ax1 = fig.add_subplot(321)  # First subplot
ax1.set_title('Original', fontsize=16, weight='bold')
ax2 = fig.add_subplot(322)  # Minimum Filter
ax2.set_title('Minimum Filter', fontsize=16, weight='bold')
ax3 = fig.add_subplot(323)  # Maximum Filter
ax3.set_title('Maximum Filter', fontsize=16, weight='bold')
ax4 = fig.add_subplot(324)  # Rank Filter
ax4.set_title('Rank Filter', fontsize=16, weight='bold')
ax5 = fig.add_subplot(325)  # Percentile Filter
ax5.set_title('Percentile Filter', fontsize=16, weight='bold')
ax6 = fig.add_subplot(326)  # Median Filter
ax6.set_title('Median Filter', fontsize=16, weight='bold')

ascent = misc.ascent()
min_filt = ndimage.minimum_filter(ascent, size=7)
max_filt = ndimage.maximum_filter(ascent, size=7)
rank_filt = ndimage.rank_filter(ascent, rank=30, size=7)
per_filt = ndimage.percentile_filter(ascent, percentile=20, size=7)
med_filt = ndimage.median_filter(ascent, size=7)

ax1.imshow(ascent)
ax2.imshow(min_filt)
ax3.imshow(max_filt)
ax4.imshow(rank_filt)
ax5.imshow(per_filt)
ax6.imshow(med_filt)

plt.show()``````
python ### 3. Derivatives

Derivative filters are commonly used in edge detection processes. Prewitt and Sobel are two such derivative filters whose direct methods are available in SciPy. Here we describe their implementation:

``````1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
``````# ===============
# Prewitt filter
# ===============
fig = plt.figure(figsize=(8, 5))
ax1.set_title('Original', fontsize=16, weight='bold')
ax2.set_title('Prewitt Filter', fontsize=16, weight='bold')

ascent = misc.ascent()
result = ndimage.prewitt(ascent)

ax1.imshow(ascent)
ax2.imshow(result)
plt.show()``````
python ``````1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
``````# ===============
# Sobel filter
# ===============
fig = plt.figure(figsize=(8, 5))
ax1.set_title('Original', fontsize=16, weight='bold')
ax2.set_title('Sobel Filter', fontsize=16, weight='bold')

ascent = misc.ascent()
result = ndimage.sobel(ascent)

ax1.imshow(ascent)
ax2.imshow(result)
plt.show()``````
python ## Conclusion

In this guide, you have learned about various filter functions which are available in SciPy `ndimage` sub-package.

To revisit on additional concepts on SciPy, you can refer the following guides:

1