Computer Vision Hough Transform
The Hough Transform finds straight lines and circles in an edge image, even when parts of the shape are missing or noisy. Road lane markings, document edges, and coins on a table all become easy targets. The method turns a hard search problem into a simple voting contest.
The Voting Idea
Imagine a classroom where every edge pixel is a student. Each student writes down every straight line that could pass through their position and casts one vote for each. Lines that many students share collect the most votes. The line with the highest tally wins, because many pixels agree on it.
Edge pixels: Votes collected per line:
. line A ||||||||||| (11 votes) <- winner
. line B ||| (3 votes)
. line C || (2 votes)
.
.
Describing a Line With Two Numbers
A vertical line breaks the familiar slope equation, so the transform uses polar form. Two numbers describe any line.
rho = shortest distance from the image corner to the line theta = angle of that shortest path Line equation: rho = x cos(theta) + y sin(theta)
Each edge pixel draws a wave-shaped curve in a table of rho and theta values. Pixels that sit on the same real line draw curves that cross at one shared cell.
The Accumulator Grid
The table that collects votes is called the accumulator. Rows hold rho values and columns hold theta values.
theta ->
0 30 60 90 120 150
rho 10 . . 1 . . .
20 . 1 . . 2 .
30 1 . . 14 . . <- bright cell = strong line
40 . . 1 . . 1
The cell with 14 votes marks a clear line. A threshold setting decides how many votes count as a real line.
Detecting Lines in Code
Edge detection comes first, since the transform needs edge pixels as input.
import cv2
import numpy as np
img = cv2.imread("road.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150)
lines = cv2.HoughLinesP(edges, rho=1, theta=np.pi / 180,
threshold=80, minLineLength=40,
maxLineGap=10)
if lines is not None:
for x1, y1, x2, y2 in lines[:, 0]:
cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)Standard and Probabilistic Versions
HoughLinesreturns endless lines described by rho and thetaHoughLinesPreturns real segments with start and end points and runs faster
Parameter Guide
Parameter Meaning Effect of raising it --------------- ------------------------------- ---------------------- threshold votes needed for a line fewer, stronger lines minLineLength shortest segment accepted drops short fragments maxLineGap largest gap that gets joined merges broken segments
Detecting Circles
A circle needs three numbers: center x, center y, and radius. Votes now fill a three-part table, so OpenCV uses a smarter gradient-based method to keep the work light. Blur the image first to avoid false circles.
gray = cv2.medianBlur(gray, 5)
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, dp=1.2,
minDist=30, param1=100, param2=40,
minRadius=10, maxRadius=80)
if circles is not None:
for x, y, r in np.round(circles[0]).astype(int):
cv2.circle(img, (x, y), r, (0, 255, 0), 2)minDistsets the smallest gap between circle centersparam2acts as the vote threshold; lower values find more circles and more false onesminRadiusandmaxRadiusnarrow the search and speed it up
Real-World Uses
- Lane marking detection in driver assistance
- Straightening tilted scanned pages
- Counting coins, bolts, and bottle caps
- Finding the horizon line in outdoor photos
Limits to Remember
Cluttered backgrounds produce many false lines. Large images slow the voting step, so resize first or crop a region of interest. Good edge maps decide the quality of every Hough result, so tune Canny thresholds before touching Hough settings.
Real-World Walkthrough: Finding Lane Lines
A dashboard camera records a road. The pipeline converts each frame to grayscale and runs Canny edge detection. A triangular mask keeps only the road area in front of the car, which removes trees and buildings. The probabilistic transform reports short segments along the painted markings. Averaging the slopes of left and right segments produces two clean lane lines.
Frame -> Grayscale -> Canny -> Road mask -> HoughLinesP -> Average slopes -> Two lane lines
Common Mistakes
- Feeding a color photo straight into the transform without edge detection
- Setting the vote threshold too low and receiving hundreds of false lines
- Skipping the blur before circle detection
- Searching the entire image when a smaller region of interest would do
Practice Exercise
Photograph a sheet of ruled paper on a desk. Detect the printed lines, measure their average angle, and rotate the image to straighten the page. The same trick fixes tilted scans before text recognition.
