Image Processing
Idea: Replace each pixel value with a function of its neighborhood using a filter kernel (e.g. a 3x3 matrix).
Standard Filters
Average
Replace each pixel with the average of its neighborhood using a filter kernel like
\[ \frac{1}{9} \cdot \begin{pmatrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \end{pmatrix} \]
Sharpen
To sharpen the original image, add the subtraction of the blurred image from the original image to the original image.
\[ \begin{pmatrix} 0 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 0 \end{pmatrix} - \frac{1}{9} \cdot \begin{pmatrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \end{pmatrix} + \begin{pmatrix} 0 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 0 \end{pmatrix} = \begin{pmatrix} -\frac{1}{9} & -\frac{1}{9} & -\frac{1}{9} \\ -\frac{1}{9} & 2 - \frac{1}{9} & -\frac{1}{9} \\ -\frac{1}{9} & -\frac{1}{9} & -\frac{1}{9} \end{pmatrix} \]
Gaussian Blur
Weight neighboring pixels by a Gaussian distribution
\[
G_\sigma = \frac{1}{2\pi\sigma^2} \cdot e^{-\frac{x^2+y^2}{2\sigma^2}}
\]
e.g. for a 5x5 kernel with \( \sigma = 1 \)
\[ \begin{pmatrix} 0.003 & 0.013 & 0.022 & 0.013 & 0.003 \\ 0.013 & 0.059 & 0.097 & 0.059 & 0.013 \\ 0.022 & 0.097 & 0.159 & 0.097 & 0.022 \\ 0.013 & 0.059 & 0.097 & 0.059 & 0.013 \\ 0.003 & 0.013 & 0.022 & 0.013 & 0.003 \end{pmatrix} \]
Gradient filters / Edge detection
The gradient \(\mathrm{grad}(f) = \begin{pmatrix} \frac{\partial f}{\partial x} & \frac{\partial f}{\partial y} \end{pmatrix}^T\) measures the rate of change of function \(f\) in the \(x\) and \(y\) directions. Hence, the magnitude \(|\mathrm{grad}(f)|\) measures how quickly the function changes.
Applying a filter using convolution
import numpy as np
def convolve(image, kernel):
# Pad image with zeros to avoid boundary effects
padded_image = np.pad(image, kernel.shape[0] // 2, mode='constant')
output = np.zeros_like(image)
# Loop over every pixel of the image
for x in range(image.shape[1]):
for y in range(image.shape[0]):
output[y, x] = (kernel * padded_image[y:y + kernel.shape[0], x:x + kernel.shape[1]]).sum()
return output
kernel = np.ones((3, 3)) / 9
filtered_image = convolve(my_image, kernel)