MediumComputer Vision

Sobel Edge Detection

Computer Vision

Medium

Problem

The Sobel operator detects image edges by estimating horizontal and vertical intensity changes. Given a two-dimensional grayscale image, compute the gradient magnitude at every pixel.

Pad the image with one row or column of zeros on every side. Use the following horizontal kernel:

K_x = \begin{bmatrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{bmatrix}

Use the following vertical kernel:

K_y = \begin{bmatrix} -1 & -2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \end{bmatrix}

For each image position with coordinates (i, j), center both kernels on that position and compute:

G_x(i,j) = \sum_{a=0}^{2}\sum_{b=0}^{2} K_x(a,b)P(i+a,j+b)

G_y(i,j) = \sum_{a=0}^{2}\sum_{b=0}^{2} K_y(a,b)P(i+a,j+b)

Combine the two directional responses:

G(i,j) = \sqrt{G_x(i,j)^2 + G_y(i,j)^2}

Here, P is the zero-padded image, i and j identify an output pixel, and a and b identify a kernel position.

Return G as a two-dimensional list of floats with the same height and width as the input image.

Theory

Edges in images are boundaries where pixel intensity changes sharply. They correspond to:

Detecting edges is fundamental to many computer vision tasks: object detection, segmentation, and feature extraction.


The Gradient Approach

Edges occur where the image intensity changes rapidly. Mathematically, this is where the gradient is large:

\nabla I = \left( \frac{\partial I}{\partial x}, \frac{\partial I}{\partial y} \right)

The gradient has two components:

The gradient magnitude tells us edge strength:

|\nabla I| = \sqrt{\left(\frac{\partial I}{\partial x}\right)^2 + \left(\frac{\partial I}{\partial y}\right)^2}


The Sobel Operator

The Sobel operator approximates image gradients using convolution with two 3x3 kernels:

Horizontal gradient kernel (Kx):

-1 0 1 -2 0 2 -1 0 1

Vertical gradient kernel (Ky):

-1 -2 -1 0 0 0 1 2 1

These kernels are designed to:


How the Kernels Work

Kx detects vertical edges:

Ky detects horizontal edges:

The weights (1, 2, 1) provide smoothing perpendicular to the gradient direction.


Step-by-Step Computation

Step 1: Pad the image

Step 2: Compute horizontal gradient

Step 3: Compute vertical gradient

Step 4: Compute magnitude

G = \sqrt{G_x^2 + G_y^2}

This gives edge strength at each pixel.


Numerical Example

Image patch (3x3) from padded image:

10 10 10 10 10 50 10 10 50

Gx computation (at center pixel):

Gy computation (at center pixel):

Magnitude: sqrt(120^2 + 40^2) = sqrt(14400 + 1600) = sqrt(16000) = 126.5

This indicates a strong edge at this position.


Gradient Direction

The gradient direction tells us the edge orientation:

\theta = \arctan\left(\frac{G_y}{G_x}\right)

This angle points perpendicular to the edge (in the direction of steepest ascent).

For the example above:

The edge is mostly vertical (gradient points mostly horizontal).


Properties of Sobel

Strengths:

Weaknesses:


Sobel vs. Other Edge Detectors

Simple finite difference:

Prewitt operator:

Scharr operator:

Canny edge detector:


Applications

Preprocessing for other algorithms:

Image analysis:

Artistic effects:


Implementation Notes

Padding:

Data types:

Normalization:

Examples

Example 1

Input
image = [[0, 0, 10, 10], [0, 0, 10, 10], [0, 0, 10, 10]]
Output
[[0.0, 31.622776601683793, 42.42640687119285, 42.42640687119285], [0.0, 40.0, 40.0, 40.0], [0.0, 31.622776601683793, 42.42640687119285, 42.42640687119285]]
Explanation
The vertical intensity transition produces large horizontal Sobel responses.

Example 2

Input
image = [[100]]
Output
[[0.0]]

Hints

  1. Copy the image into the center of a grid with a one-pixel zero border.
  2. Accumulate horizontal and vertical kernel responses before taking their Euclidean magnitude.

Requirements

Constraints

Starter Code

import math

def sobel_edges(image: list) -> list:
    """
    Returns the zero-padded Sobel gradient magnitude at every pixel.
    """
    # Write code here
    pass

Test Cases

CaseMatches
vert edgepublic
singlepublic