Skip to content

Image Processing

This document covers colormaps and image manipulation techniques in matplotlib.

Colormaps (cmap)

The cmap parameter specifies the colormap used to map scalar data to colors.

Official Documentation

Basic Usage

import matplotlib.pyplot as plt
import numpy as np

data = np.random.rand(10, 10)

fig, axes = plt.subplots(1, 3, figsize=(12, 4))

axes[0].imshow(data, cmap='viridis')
axes[0].set_title('viridis')

axes[1].imshow(data, cmap='plasma')
axes[1].set_title('plasma')

axes[2].imshow(data, cmap='gray')
axes[2].set_title('gray')

for ax in axes:
    ax.axis('off')
plt.tight_layout()
plt.show()

Colormap Categories

Perceptually Uniform Sequential

import matplotlib.pyplot as plt
import numpy as np

data = np.random.rand(50, 50)
cmaps = ['viridis', 'plasma', 'inferno', 'magma', 'cividis']

fig, axes = plt.subplots(1, 5, figsize=(15, 3))
for ax, cmap in zip(axes, cmaps):
    ax.imshow(data, cmap=cmap)
    ax.set_title(cmap)
    ax.axis('off')
plt.tight_layout()
plt.show()

Sequential

cmaps = ['Greys', 'Blues', 'Greens', 'Oranges', 'Reds']

fig, axes = plt.subplots(1, 5, figsize=(15, 3))
for ax, cmap in zip(axes, cmaps):
    ax.imshow(data, cmap=cmap)
    ax.set_title(cmap)
    ax.axis('off')
plt.tight_layout()
plt.show()

Diverging

# Diverging data centered at 0
data = np.random.randn(50, 50)
cmaps = ['RdBu', 'RdYlGn', 'coolwarm', 'bwr', 'seismic']

fig, axes = plt.subplots(1, 5, figsize=(15, 3))
for ax, cmap in zip(axes, cmaps):
    im = ax.imshow(data, cmap=cmap, vmin=-2, vmax=2)
    ax.set_title(cmap)
    ax.axis('off')
plt.tight_layout()
plt.show()

Cyclic

# Cyclic data (e.g., angles)
x = np.linspace(-np.pi, np.pi, 100)
y = np.linspace(-np.pi, np.pi, 100)
X, Y = np.meshgrid(x, y)
data = np.arctan2(Y, X)

cmaps = ['twilight', 'twilight_shifted', 'hsv']

fig, axes = plt.subplots(1, 3, figsize=(12, 4))
for ax, cmap in zip(axes, cmaps):
    ax.imshow(data, cmap=cmap)
    ax.set_title(cmap)
    ax.axis('off')
plt.tight_layout()
plt.show()

Grayscale Images

import matplotlib.pyplot as plt
import numpy as np

digit = np.random.rand(28, 28)

fig, axes = plt.subplots(1, 4, figsize=(12, 3))

axes[0].imshow(digit, cmap='gray')
axes[0].set_title('gray')

axes[1].imshow(digit, cmap='binary')
axes[1].set_title('binary')

axes[2].imshow(digit, cmap='gray_r')
axes[2].set_title('gray_r (reversed)')

axes[3].imshow(digit, cmap='binary_r')
axes[3].set_title('binary_r')

for ax in axes:
    ax.axis('off')
plt.tight_layout()
plt.show()

Reversed Colormaps

Add _r suffix to reverse any colormap:

import matplotlib.pyplot as plt
import numpy as np

data = np.random.rand(50, 50)

fig, axes = plt.subplots(2, 3, figsize=(12, 8))

cmaps = ['viridis', 'hot', 'Blues']
for i, cmap in enumerate(cmaps):
    axes[0, i].imshow(data, cmap=cmap)
    axes[0, i].set_title(cmap)
    axes[0, i].axis('off')

    axes[1, i].imshow(data, cmap=cmap + '_r')
    axes[1, i].set_title(cmap + '_r')
    axes[1, i].axis('off')

plt.tight_layout()
plt.show()

Value Range Control (vmin, vmax)

import matplotlib.pyplot as plt
import numpy as np

data = np.random.rand(50, 50) * 100  # Range 0-100

fig, axes = plt.subplots(1, 3, figsize=(12, 4))

axes[0].imshow(data, cmap='viridis')
axes[0].set_title('Default range')

axes[1].imshow(data, cmap='viridis', vmin=25, vmax=75)
axes[1].set_title('vmin=25, vmax=75')

axes[2].imshow(data, cmap='viridis', vmin=0, vmax=50)
axes[2].set_title('vmin=0, vmax=50')

for ax in axes:
    ax.axis('off')
plt.tight_layout()
plt.show()

Adding Colorbar

import matplotlib.pyplot as plt
import numpy as np

data = np.random.rand(50, 50)

fig, ax = plt.subplots()
im = ax.imshow(data, cmap='viridis')
fig.colorbar(im, ax=ax, label='Value')
ax.set_title('Image with Colorbar')
plt.show()

Image Manipulation

Manipulate images using NumPy array indexing and slicing operations.

Image as 3D Array

import matplotlib.pyplot as plt
import numpy as np
import PIL
import urllib

url = "https://upload.wikimedia.org/wikipedia/en/4/43/Pok%C3%A9mon_Mewtwo_art.png"
img = np.array(PIL.Image.open(urllib.request.urlopen(url)))
print(img.shape)  # (height, width, channels)

Common Transformations

import matplotlib.pyplot as plt
import numpy as np
import PIL
import urllib

def main():
    url = "https://upload.wikimedia.org/wikipedia/en/4/43/Pok%C3%A9mon_Mewtwo_art.png"
    img = np.array(PIL.Image.open(urllib.request.urlopen(url)))

    imgs = (
        img,              # Original
        img[::-1],        # Vertical flip
        img[:, ::-1],     # Horizontal flip
        img[:, :, ::-1],  # Channel reverse (RGB to BGR)
        img[::7, ::7],    # Downsampling
        img[50:-50, 50:-50]  # Cropping
    )

    imgs_title = (
        "img",
        "img[::-1]",
        "img[:, ::-1]",
        "img[:, :, ::-1]",
        "img[::7, ::7]",
        "img[50:-50, 50:-50]"
    )

    fig, axes = plt.subplots(2, 3, figsize=(8, 5))
    for ax, img_to_plot, img_title in zip(axes.flatten(), imgs, imgs_title):
        ax.set_title(img_title, fontsize=12)
        ax.imshow(img_to_plot)
        ax.axis('off')
    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    main()

Transformation Reference

Operation Code Description
Vertical flip img[::-1] Reverse rows
Horizontal flip img[:, ::-1] Reverse columns
180° rotation img[::-1, ::-1] Reverse both
RGB to BGR img[:, :, ::-1] Reverse channels
Downsampling img[::n, ::n] Take every nth pixel
Cropping img[y1:y2, x1:x2] Extract region

Channel Operations

Visualize Individual Channels

import matplotlib.pyplot as plt
import numpy as np
import PIL
import urllib

url = "https://upload.wikimedia.org/wikipedia/en/4/43/Pok%C3%A9mon_Mewtwo_art.png"
img = np.array(PIL.Image.open(urllib.request.urlopen(url)))

fig, axes = plt.subplots(1, 4, figsize=(16, 4))

axes[0].imshow(img)
axes[0].set_title('Original')

axes[1].imshow(img[:, :, 0], cmap='Reds')
axes[1].set_title('Red Channel')

axes[2].imshow(img[:, :, 1], cmap='Greens')
axes[2].set_title('Green Channel')

axes[3].imshow(img[:, :, 2], cmap='Blues')
axes[3].set_title('Blue Channel')

for ax in axes:
    ax.axis('off')
plt.tight_layout()
plt.show()

Swap Channels

# Create different channel arrangements
img_rbg = img[:, :, [0, 2, 1]]  # R, B, G
img_grb = img[:, :, [1, 0, 2]]  # G, R, B
img_gbr = img[:, :, [1, 2, 0]]  # G, B, R
img_brg = img[:, :, [2, 0, 1]]  # B, R, G
img_bgr = img[:, :, [2, 1, 0]]  # B, G, R

Image Grid Overlay

import matplotlib.pyplot as plt
import numpy as np
import PIL
import urllib

url = "https://upload.wikimedia.org/wikipedia/en/4/43/Pok%C3%A9mon_Mewtwo_art.png"
img = np.array(PIL.Image.open(urllib.request.urlopen(url)))

fig, (ax0, ax1) = plt.subplots(1, 2, figsize=(10, 5))

ax0.imshow(img)
ax0.set_title('Original')

spacing = 50
img_copy = img.copy()
img_copy[spacing:-1:spacing, :] = [255, 0, 0, 1]  # Horizontal red lines
img_copy[:, spacing:-1:spacing] = [255, 0, 0, 1]  # Vertical red lines
ax1.imshow(img_copy)
ax1.set_title('With Grid')

for ax in (ax0, ax1):
    ax.axis('off')

plt.tight_layout()
plt.show()

Regions of Interest (ROI)

import matplotlib.pyplot as plt
import numpy as np
import PIL
import urllib

url = "https://upload.wikimedia.org/wikipedia/en/4/43/Pok%C3%A9mon_Mewtwo_art.png"
img = np.array(PIL.Image.open(urllib.request.urlopen(url)))

# Define region of interest
y_start, y_end = 100, 200
x_start, x_end = 50, 150

# Extract ROI
roi = img[y_start:y_end, x_start:x_end]

# Create highlighted version
img_highlight = img.copy()
img_highlight[y_start:y_end, x_start:x_end, 0] = 255  # Add red tint

fig, axes = plt.subplots(1, 3, figsize=(12, 4))

axes[0].imshow(img)
axes[0].set_title('Original')

axes[1].imshow(img_highlight)
axes[1].set_title('Highlighted ROI')

axes[2].imshow(roi)
axes[2].set_title('Extracted ROI')

for ax in axes:
    ax.axis('off')
plt.tight_layout()
plt.show()

Image Tiling

import matplotlib.pyplot as plt
import numpy as np

def tile_image(img, rows, cols):
    """Tile an image into a grid."""
    return np.tile(img, (rows, cols, 1))

# Create 2x3 tiled image
tiled = tile_image(img, 2, 3)

fig, ax = plt.subplots(figsize=(12, 8))
ax.imshow(tiled)
ax.axis('off')
plt.show()

Adding Borders

import matplotlib.pyplot as plt
import numpy as np

def add_border(img, size=10, color=[255, 0, 0]):
    """Add a colored border to an image."""
    bordered = img.copy()
    bordered[:size, :] = color      # Top
    bordered[-size:, :] = color     # Bottom
    bordered[:, :size] = color      # Left
    bordered[:, -size:] = color     # Right
    return bordered

bordered = add_border(img, size=20, color=[255, 0, 0])

fig, ax = plt.subplots()
ax.imshow(bordered)
ax.axis('off')
plt.show()

Colormap Reference

Categories Summary

Category Colormaps Use Case
Perceptually Uniform viridis, plasma, inferno, magma General purpose
Sequential Greys, Blues, Greens, Oranges Single-direction data
Diverging RdBu, coolwarm, bwr Data with center point
Cyclic twilight, hsv Periodic data (angles)
Qualitative Set1, Set2, Pastel1 Categorical data