Edges outline objects and feed contour finding, line detection and many classic measurement pipelines.
An edge is where intensity changes sharply. cv2.Sobel(gray, ddepth, dx, dy, ksize) estimates the derivative in x or y. Use a signed output depth such as cv2.CV_16S or cv2.CV_64F: with uint8 output, negative slopes (light-to-dark edges) are clipped to zero and lost. Convert back for display with cv2.convertScaleAbs. cv2.Laplacian gives the second derivative and is a quick focus or blur measure: its variance drops for blurry images.
The Canny detector, cv2.Canny(gray, low, high), turns gradients into thin, connected edge lines:
- it smooths and computes gradient magnitude and direction,
- keeps only local maxima across the edge (non-maximum suppression), giving one-pixel-wide lines,
- applies hysteresis: pixels above
highare edges, pixels betweenlowandhighsurvive only if connected to a strong edge.
A ratio of about 1:2 or 1:3 between low and high is typical. A common heuristic derives both from the median intensity of the image. Blur first if the image is noisy, or Canny will report texture as edges.
Canny returns a binary uint8 image (0 or 255), ready for findContours or cv2.HoughLinesP to detect straight segments.
Example
import cv2
import numpy as np
img = np.zeros((60, 60), np.uint8)
img[:, 30:] = 200 # vertical step edge at x = 30
gx8 = cv2.Sobel(img[:, ::-1].copy(), cv2.CV_8U, 1, 0) # dark-to-light reversed
print(gx8.max()) # 0 -- negative slope clipped away!
gx = cv2.Sobel(img[:, ::-1].copy(), cv2.CV_16S, 1, 0)
print(gx.min()) # -800 kept with a signed depth
print(cv2.convertScaleAbs(gx).max()) # 255 for display
edges = cv2.Canny(img, 50, 150)
print(np.unique(edges)) # [ 0 255]
print(np.nonzero(edges[30])[0]) # one-pixel wide edge near x = 30
sharp_var = cv2.Laplacian(img, cv2.CV_64F).var()
blurry_var = cv2.Laplacian(cv2.GaussianBlur(img, (9, 9), 0), cv2.CV_64F).var()
print(sharp_var > blurry_var) # True: a simple blur detectorRemember
- Use a signed ddepth (CV_16S, CV_64F) for Sobel so negative gradients survive
- Canny gives thin binary edges using two hysteresis thresholds
- Blur noisy images before edge detection
- Variance of the Laplacian is a quick sharpness score
Watch out for
- Running Sobel with a uint8 output and losing every light-to-dark edge.