Inicio > Cursos > Computer Vision con Python > Contornos y Analisis de Formas
Computer Vision con PythonFundamentos de VisionLección 5 de 12

Contornos y Analisis de Formas

Los contornos son curvas que conectan los puntos de borde de un objeto. Con findContours extraes las siluetas y luego puedes medir area, perimetro, centro de masa y clasificar formas geometricas.

Flujo tipico: 1. Convertir a gris → threshold o Canny para obtener binaria 2. findContours para extraer contornos 3. Filtrar por area (eliminar ruido) 4. Analizar cada contorno: area, perimetro, bounding box 5. Clasificar forma con approxPolyDP (vertices)

import cv2
import numpy as np

img = cv2.imread("formas.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV)

# Encontrar contornos
contornos, jerarquia = cv2.findContours(
    thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
# RETR_EXTERNAL: solo contornos externos (ignora hijos)
# RETR_TREE: todos con jerarquia completa

for cnt in contornos:
    area = cv2.contourArea(cnt)
    if area < 100:  # Filtrar ruido
        continue
    
    perimetro = cv2.arcLength(cnt, closed=True)
    
    # Bounding box (rectangulo que encierra el contorno)
    x, y, w, h = cv2.boundingRect(cnt)
    cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
    
    # Circulo minimo
    (cx, cy), radio = cv2.minEnclosingCircle(cnt)
    
    # Centro de masa (momentos)
    M = cv2.moments(cnt)
    if M["m00"] > 0:
        centro_x = int(M["m10"] / M["m00"])
        centro_y = int(M["m01"] / M["m00"])
        cv2.circle(img, (centro_x, centro_y), 5, (0, 0, 255), -1)
def clasificar_forma(cnt):
    """Clasifica forma geometrica por numero de vertices"""
    perimetro = cv2.arcLength(cnt, True)
    # approxPolyDP simplifica el contorno a un poligono
    approx = cv2.approxPolyDP(cnt, 0.04 * perimetro, True)
    vertices = len(approx)
    
    if vertices == 3:
        return "Triangulo"
    elif vertices == 4:
        # Diferenciar cuadrado de rectangulo
        x, y, w, h = cv2.boundingRect(approx)
        ratio = w / float(h)
        return "Cuadrado" if 0.9 <= ratio <= 1.1 else "Rectangulo"
    elif vertices == 5:
        return "Pentagono"
    elif vertices > 6:
        # Verificar circularidad
        area = cv2.contourArea(cnt)
        circularidad = 4 * np.pi * area / (perimetro ** 2)
        return "Circulo" if circularidad > 0.8 else f"Poligono ({vertices})"
    return f"Poligono ({vertices})"

# Detectar y clasificar todas las formas
for cnt in contornos:
    if cv2.contourArea(cnt) < 100:
        continue
    forma = clasificar_forma(cnt)
    x, y, w, h = cv2.boundingRect(cnt)
    cv2.putText(img, forma, (x, y - 10),
        cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 0, 0), 2)
    cv2.drawContours(img, [cnt], -1, (0, 255, 0), 2)
ConsejoEl parametro epsilon de approxPolyDP controla la precision: 0.01*perimetro = muy preciso (muchos vertices), 0.05*perimetro = mas simplificado (pocos vertices). Usa 0.04 como punto de partida.
← Operaciones MorfologicasDeteccion y reconocimiento facial →

Practica esta lección

Resuelve los ejercicios del curso de Computer Vision con Python en la app, gratis y con corrección automática.

Empezar a practicar