Skip to content

SciPy - Ndimage

SciPy - Multidimensional Image Processing (scipy.ndimage)

Section titled “SciPy - Multidimensional Image Processing (scipy.ndimage)”

The scipy.ndimage module is dedicated to N-dimensional image processing. It provides a wide range of functions for filtering, interpolation, measurements, morphology, and other common image manipulation tasks on NumPy arrays.

Common image processing tasks that can be addressed with scipy.ndimage include:

  • Reading/Writing images (often with help from other libraries like Matplotlib or ImageIO).
  • Basic manipulations: Cropping, flipping, rotating.
  • Image filtering: Denoising, sharpening, blurring (e.g., Gaussian filter).
  • Morphological operations: Erosion, dilation, opening, closing.
  • Object measurements: Finding centers of mass, labeling features.
  • Interpolation and geometric transformations.

For more advanced image analysis (e.g., feature detection like SIFT/SURF, complex segmentation algorithms), libraries like scikit-image, OpenCV, or Mahotas are typically used in conjunction with or as alternatives to scipy.ndimage.

SciPy itself doesn’t focus on image I/O. scipy.datasets.face() provides a sample color image (a racoon) as a NumPy array. For general image loading, libraries like matplotlib.image or imageio are recommended.

from scipy import datasets # For the sample image
import matplotlib.pyplot as plt
import numpy as np
# Load the sample 'face' image (a racoon)
# It's a 3D NumPy array (height, width, color_channels)
face_color = datasets.face()
# Load a grayscale version if available, or convert
# face_gray = datasets.face(gray=True) # This was an option in older scipy.misc
# For current datasets.face(), convert manually if needed:
face_gray = np.mean(face_color, axis=2).astype(np.uint8)
# Display the image using Matplotlib
fig, axes = plt.subplots(1, 2, figsize=(10, 5))
axes[0].imshow(face_color)
axes[0].set_title('Color Face Image')
axes[0].axis('off')
axes[1].imshow(face_gray, cmap='gray')
axes[1].set_title('Grayscale Face Image')
axes[1].axis('off')
plt.tight_layout()
# plt.show()
# Description: This code loads a sample image of a racoon, once in color and
# once converted to grayscale. It then displays both side-by-side using Matplotlib.

An image in its raw digital form is essentially a NumPy array where pixel values represent intensities or colors. For a grayscale image, it’s typically a 2D array. For a color image (e.g., RGB), it’s a 3D array (height, width, 3).

Basic image statistics:

from scipy import datasets
import numpy as np
face = datasets.face() # Color image
print(f"Image shape: {face.shape}")
print(f"Data type: {face.dtype}")
print(f"Mean pixel value (overall): {face.mean():.2f}")
print(f"Max pixel value: {face.max()}")
print(f"Min pixel value: {face.min()}")

Output (will vary slightly based on SciPy version/dataset exacts):

Image shape: (768, 1024, 3)
Data type: uint8
Mean pixel value (overall): 114.51
Max pixel value: 255
Min pixel value: 0

Since images are NumPy arrays, basic transformations like cropping can be done using array slicing. scipy.ndimage provides functions for more complex transformations like rotation and scaling.

from scipy import datasets
import matplotlib.pyplot as plt
import numpy as np
face_gray = np.mean(datasets.face(), axis=2).astype(np.uint8)
height, width = face_gray.shape
# Crop the central part of the image
# Remove 1/4th from each side (top, bottom, left, right)
crop_start_h, crop_end_h = height // 4, height - height // 4
crop_start_w, crop_end_w = width // 4, width - width // 4
cropped_face = face_gray[crop_start_h:crop_end_h, crop_start_w:crop_end_w]
plt.figure(figsize=(5, 5))
plt.imshow(cropped_face, cmap='gray')
plt.title('Cropped Grayscale Face')
plt.axis('off')
# plt.show()
# Description: This code will display the central cropped portion of the grayscale racoon image.

NumPy’s flipud (flip up-down) and fliplr (flip left-right) are useful.

from scipy import datasets
import numpy as np
import matplotlib.pyplot as plt
face_color = datasets.face()
# Flip upside down
flipped_ud_face = np.flipud(face_color)
plt.figure(figsize=(5,5))
plt.imshow(flipped_ud_face)
plt.title('Up-Down Flipped Face')
plt.axis('off')
# plt.show()
# Description: This code will display the racoon image flipped vertically.

The scipy.ndimage.rotate() function rotates an image by a specified angle (in degrees).

from scipy import datasets, ndimage
import matplotlib.pyplot as plt
face_color = datasets.face()
# Rotate the image by 45 degrees. By default, fills outside areas with 0.
# 'reshape=False' keeps original image dimensions, cropping rotated parts.
rotated_face = ndimage.rotate(face_color, 45, reshape=False)
plt.figure(figsize=(5,5))
plt.imshow(rotated_face)
plt.title('Rotated Face (45 degrees)')
plt.axis('off')
# plt.show()
# Description: This code will display the racoon image rotated by 45 degrees clockwise,
# with parts of the image outside the original bounds cropped.

Filtering modifies pixel values based on their neighborhood, used for tasks like smoothing, sharpening, and edge detection.

A Gaussian filter smooths an image and reduces noise. scipy.ndimage.gaussian_filter(input, sigma) applies this. sigma is the standard deviation of the Gaussian kernel; larger sigma means more blur.

from scipy import datasets, ndimage
import matplotlib.pyplot as plt
import numpy as np
face_gray = np.mean(datasets.face(), axis=2).astype(np.uint8)
# Apply Gaussian filter with sigma = 3
blurred_face = ndimage.gaussian_filter(face_gray, sigma=3)
# Apply Gaussian filter with sigma = 7 for more blur
more_blurred_face = ndimage.gaussian_filter(face_gray, sigma=7)
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
axes[0].imshow(face_gray, cmap='gray')
axes[0].set_title('Original Grayscale')
axes[0].axis('off')
axes[1].imshow(blurred_face, cmap='gray')
axes[1].set_title('Blurred (sigma=3)')
axes[1].axis('off')
axes[2].imshow(more_blurred_face, cmap='gray')
axes[2].set_title('More Blurred (sigma=7)')
axes[2].axis('off')
plt.tight_layout()
# plt.show()
# Description: This code displays the original grayscale image alongside two versions
# blurred with a Gaussian filter using different sigma values (3 and 7).
# The image with sigma=7 will appear more blurred.

Edge detection aims to identify significant changes in brightness, corresponding to object boundaries.

The Sobel filter is a common gradient-based edge detector. scipy.ndimage.sobel(input, axis, output) computes the Sobel filter along a given axis. The results from x and y axes are often combined to get the overall edge magnitude.

from scipy import ndimage, datasets
import numpy as np
import matplotlib.pyplot as plt
# Create a simple synthetic image for clear edge detection
image = np.zeros((128, 128))
image[32:-32, 32:-32] = 1 # A white square on a black background
# Add some noise and blur to make it more realistic
image = image + 0.1 * np.random.rand(128,128)
image = ndimage.gaussian_filter(image, sigma=2)
# Apply Sobel filter along x-axis (axis=1 for columns/horizontal gradient)
sobel_x = ndimage.sobel(image, axis=1, mode='reflect')
# Apply Sobel filter along y-axis (axis=0 for rows/vertical gradient)
sobel_y = ndimage.sobel(image, axis=0, mode='reflect')
# Combine to get edge magnitude
sobel_magnitude = np.hypot(sobel_x, sobel_y)
fig, axes = plt.subplots(1, 4, figsize=(16, 4))
axes[0].imshow(image, cmap='gray')
axes[0].set_title('Original Synthetic Image')
axes[0].axis('off')
axes[1].imshow(sobel_x, cmap='gray')
axes[1].set_title('Sobel X (Horizontal Edges)')
axes[1].axis('off')
axes[2].imshow(sobel_y, cmap='gray')
axes[2].set_title('Sobel Y (Vertical Edges)')
axes[2].axis('off')
axes[3].imshow(sobel_magnitude, cmap='gray')
axes[3].set_title('Sobel Magnitude (Edges)')
axes[3].axis('off')
plt.tight_layout()
# plt.show()
# Description: This code generates a synthetic image of a square, then applies the
# Sobel filter to detect its horizontal and vertical edges, and finally shows the
# combined edge magnitude. The last image highlights the boundaries of the square.

scipy.ndimage offers many more functionalities, including morphological operations (e.g., binary_erosion, binary_dilation), feature measurements (center_of_mass, label), and interpolation (zoom, map_coordinates). For detailed information, consult the official SciPy ndimage documentation.