Trabajo de Visión por Computador: Detección de Bordes
Byron Velasco Cueva, Alex Perez Vilañez, Paúl Cortés Barahona
byvelascocu@[Link], alperezvi@[Link], pacortesba@[Link]
Resumen
El procesamiento digital de imágenes constituye una rama esencial de la visión por computador, permitiendo la extracción
de información significativa a partir de fuentes visuales digitales. Dentro de este campo, la detección de bordes es una tarea
crı́tica, ya que estos cambios bruscos de intensidad suelen delimitar los objetos en una escena. En el presente proyecto se
implementa el algoritmo Canny Edge Detection, reconocido por su robustez y capacidad para generar contornos definidos
minimizando el ruido. La implementación se apoya en librerı́as estándar como OpenCV, NumPy y Matplotlib. Además, se
introduce una variación controlada de parámetros mediante una semilla aleatoria (seed) y se añade una funcionalidad para
la detección en tiempo real mediante webcam.
1. Introducción
El procesamiento digital de imágenes es fundamental en la visión por computador, ya que permite extraer
información relevante a partir de imágenes digitales. Una de las tareas más importantes dentro de este campo
es la detección de bordes, pues estos representan cambios bruscos de intensidad que suelen corresponder a los
lı́mites fı́sicos de los objetos presentes en la escena.
En este proyecto se implementa el algoritmo Canny Edge Detection [1], uno de los métodos más robustos y
utilizados para la detección de bordes. Este algoritmo es preferido debido a su excelente respuesta ante el ruido y
su capacidad para producir contornos bien definidos y continuos.
La implementación se realiza utilizando las librerı́as OpenCV [2], NumPy [3] y Matplotlib [4], herramientas
ampliamente empleadas en aplicaciones modernas de visión por computador. Adicionalmente, se incorpora el
uso de una semilla aleatoria (seed ) para generar variaciones controladas en los parámetros del algoritmo, lo
que permite obtener resultados distintos sobre una misma imagen para fines experimentales. Finalmente, como
funcionalidad adicional (bonus), se implementa la detección de bordes en tiempo real utilizando la captura de
video de una webcam.
2. Tecnologı́as Utilizadas
Para el desarrollo de esta práctica se han utilizado las siguientes herramientas tecnológicas:
Python [5]: Lenguaje principal de desarrollo debido a su versatilidad y potencia en ciencia de datos.
OpenCV (cv2) [2]: Biblioteca estándar de la industria utilizada para la carga de imágenes, conversión a
escala de grises, detección de bordes y captura de video en tiempo real.
NumPy [3]: Utilizado para la manipulación eficiente de arreglos numéricos y la generación de ruido
aleatorio controlado.
Matplotlib [4]: (Opcional en el código) Empleado para la visualización de datos y gráficos posteriores.
Webcam / Cámara: Hardware utilizado para la validación del algoritmo en tiempo real.
1
Universidad Internacional del Ecuador Maestrı́a en IA Aplicada
3. Metodologı́a y Flujo del Programa
El software desarrollado sigue un flujo lineal de procesamiento, enriquecido con interactividad. Los pasos
principales son:
1. Carga de imagen o captura: Se obtiene la entrada visual desde un archivo local o directamente desde
la webcam.
2. Conversión a escala de grises: La imagen se transforma utilizando [Link]. Este paso es crucial
ya que el algoritmo Canny opera sobre imágenes de un solo canal (monocromáticas).
3. Aplicación de Canny Edge Detection: Se ejecuta el algoritmo [1] sobre la imagen procesada.
4. Variación de parámetros (Seed): Se utiliza una semilla aleatoria para modificar dinámicamente los
umbrales del detector, permitiendo observar la sensibilidad del algoritmo.
5. Visualización: Se presentan en pantalla los resultados finales.
3.1 Aplicación del algoritmo Canny
El detector de bordes Canny se configura mediante dos parámetros crı́ticos: el umbral bajo (threshold1 ) y el
umbral alto (threshold2 ). En nuestra implementación, estos valores no son estáticos; se modifican automáticamente
usando la semilla aleatoria, facilitando el análisis de cómo diferentes configuraciones afectan la detección de
bordes en la misma escena.
3.2 Uso de semilla (seed)
La incorporación de la semilla permite:
Variar los umbrales del algoritmo de forma determinista.
Añadir ruido controlado a la imagen para probar la robustez.
Obtener resultados distintos pero reproducibles, lo cual es vital para la experimentación cientı́fica.
4. Pruebas del Código
4.1 Prueba con imagen local
El sistema permite cargar una imagen desde el disco y procesarla paso a paso: mostrando la imagen original,
la conversión a escala de grises y finalmente los bordes detectados. Además, la consola muestra los valores reales
de los umbrales utilizados en cada ejecución.
2
Universidad Internacional del Ecuador Maestrı́a en IA Aplicada
Figura 1. Comparativa: Imagen Original vs. Detección de Bordes Canny (Imagen Local).
4.2 Prueba en tiempo real con webcam (Bonus)
Como funcionalidad extra, se habilitó el uso de la cámara web. El usuario dispone de los siguientes controles
en tiempo real:
q: Salir del programa.
n: Incrementar la semilla (cambia los parámetros aleatorios).
p: Disminuir la semilla.
r: Reiniciar la semilla a su valor original.
Esto permite observar en vivo cómo la iluminación y el movimiento, junto con los cambios de parámetros, afectan
la detección.
Figura 2. Detección de bordes en tiempo real utilizando la webcam.
5. Resultados
Los experimentos realizados arrojan las siguientes observaciones:
3
Universidad Internacional del Ecuador Maestrı́a en IA Aplicada
El algoritmo Canny [1] demostró ser altamente efectivo para detectar bordes bien definidos, ignorando
texturas suaves.
La conversión a escala de grises es un paso pre-procesamiento indispensable que mejora significativamente
el rendimiento.
La variación de la semilla permitió visualizar que umbrales más bajos capturan más detalles (incluyendo
ruido), mientras que umbrales más altos producen bordes más limpios pero pueden perder contornos
importantes.
En la prueba de tiempo real, el sistema respondió adecuadamente, manteniendo una tasa de cuadros estable
en la mayorı́a de los escenarios probados.
6. Conclusiones
Se concluye que el algoritmo Canny Edge Detection es una técnica robusta y confiable para la detección de
bordes en imágenes digitales. El uso de herramientas como OpenCV [2] y NumPy [3] facilita enormemente su
implementación.
La incorporación de una semilla aleatoria resultó ser una estrategia valiosa para analizar el impacto de los
parámetros del algoritmo, asegurando al mismo tiempo la reproducibilidad de los resultados. Finalmente, la
implementación en tiempo real demuestra la viabilidad de este método para aplicaciones prácticas en visión
artificial, robótica y sistemas de monitoreo. Este proyecto sienta una base sólida para trabajos futuros como la
segmentación de imágenes y el reconocimiento de objetos.
Referencias Bibliográficas
[1] John Canny. “A computational approach to edge detection”. En: IEEE Transactions on Pattern Analysis
and Machine Intelligence 6 (1986), págs. 679-698.
[2] Gary Bradski. “The OpenCV Library”. En: Dr. Dobb’s Journal of Software Tools 25.11 (2000), págs. 120-123.
[3] Charles R. Harris et al. “Array programming with NumPy”. En: Nature 585.7825 (2020), págs. 357-362.
[4] John D. Hunter. “Matplotlib: A 2D graphics environment”. En: Computing in Science & Engineering 9.3
(2007), págs. 90-95.
[5] Guido Van Rossum y Fred L. Drake. Python 3 Reference Manual. Scotts Valley, CA: CreateSpace, 2009.
4
Universidad Internacional del Ecuador Maestrı́a en IA Aplicada
A. Anexos: Código Fuente
A continuación, se adjunta el código completo generado en Python para realizar la práctica.
A.1 Lógica de Canny y Procesamiento de Imagen Local
1 import argparse
2 import time
3 from typing import Optional , Tuple
4 import cv2
5 import numpy as np
6
7 def ca n ny _w it h _s ee d (
8 gray_img : np . ndarray ,
9 seed : int = 0 ,
10 base_low : int = 80 ,
11 base_high : int = 160 ,
12 add_noise : bool = True ,
13 noise_sigma : float = 6.0 ,
14 ) -> Tuple [ np . ndarray , int , int ]:
15
16 # Generador de n ú meros aleatorios usando la semilla
17 rng = np . random . default_rng ( seed )
18
19 # Se modifican los umbrales de Canny de forma controlada
20 low = int ( np . clip ( base_low + rng . integers ( -40 , 41) , 0 , 255) )
21 high = int ( np . clip ( base_high + rng . integers ( -40 , 41) , 0 , 255) )
22
23 # Asegurar que high sea mayor que low
24 if high <= low :
25 high = min (255 , low + 50)
26
27 img_proc = gray_img
28
29 # Agregar ruido gaussiano controlado por la semilla
30 if add_noise :
31 noise = rng . normal (0.0 , noise_sigma , size = gray_img . shape ) . astype ( np . float32 )
32 img_proc = np . clip ( gray_img . astype ( np . float32 ) + noise , 0 , 255) . astype ( np . uint8 )
33
34 # Aplicar el algoritmo Canny Edge Detection
35 edges = cv2 . Canny ( img_proc , threshold1 = low , threshold2 = high )
36 return edges , low , high
37
38 def process_image ( image_path : str , seed : int , base_low : int , base_high : int , add_noise : bool )
-> None :
39 img_bgr = cv2 . imread ( image_path )
40 if img_bgr is None :
41 raise F i l e N o t F o u n d E r r o r ( f " No se puede leer la imagen : { image_path } " )
42
43 gray = cv2 . cvtColor ( img_bgr , cv2 . COL OR_BGR2 GRAY )
44 edges , low , high = c an ny _w i th _s ee d (
45 gray , seed = seed , base_low = base_low , base_high = base_high , add_noise = add_noise
46 )
47
48 cv2 . imshow ( " Original " , img_bgr )
49 cv2 . imshow ( f " Canny ( seed ={ seed }) " , edges )
50 print ( f " [ Imagen ] seed ={ seed } | t1 ={ low } | t2 ={ high } " )
51 cv2 . waitKey (0)
52 cv2 . d e s t r o y A l l W i n d o w s ()
Listing 1. Funciones Base y Canny con Semilla
A.2 Procesamiento en Tiempo Real y Función Principal
1 def pr ocess_w ebcam (
2 cam_index : int , seed : int , base_low : int , base_high : int ,
3 add_noise : bool , width : Optional [ int ] , height : Optional [ int ] ,
5
Universidad Internacional del Ecuador Maestrı́a en IA Aplicada
4 fps_limit : Optional [ float ]
5 ) -> None :
6 cap = cv2 . VideoCapture ( cam_index , cv2 . CAP_DSHOW )
7 if not cap . isOpened () :
8 raise RuntimeError ( f " Error al abrir webcam { cam_index }. " )
9
10 if width : cap . set ( cv2 . CAP_PROP_FRAME_WIDTH , float ( width ) )
11 if height : cap . set ( cv2 . CAP_PROP_FRAME_HEIGHT , float ( height ) )
12
13 print ( " Controles : q = salir | n = seed +1 | p = seed -1 | r = reset " )
14 last_time = time . time ()
15
16 while True :
17 ret , frame = cap . read ()
18 if not ret : break
19
20 gray = cv2 . cvtColor ( frame , cv2 . COLOR_ BGR2GRA Y )
21 edges , low , high = c an ny _w i th _s ee d (
22 gray , seed = seed , base_low = base_low , base_high = base_high , add_noise = add_noise
23 )
24
25 cv2 . imshow ( " Webcam Canny " , edges )
26
27 # Control de FPS
28 if fps_limit and fps_limit > 0:
29 dt = time . time () - last_time
30 target = 1.0 / fps_limit
31 if dt < target : time . sleep ( target - dt )
32 last_time = time . time ()
33
34 key = cv2 . waitKey (1) & 0 xFF
35 if key == ord ( " q " ) : break
36 elif key == ord ( " n " ) : seed += 1
37 elif key == ord ( " p " ) : seed -= 1
38 elif key == ord ( " r " ) : seed = 0
39
40 cap . release ()
41 cv2 . d e s t r o y A l l W i n d o w s ()
42
43 def main () :
44 parser = argparse . Argumen tParser ()
45 parser . add_argument ( " -- image " , type = str , default = None )
46 parser . add_argument ( " -- webcam " , action = " store_true " )
47 # ... ( resto de argumentos )
48 args = parser . parse_args ()
49
50 if args . image :
51 process_image ( args . image , args . seed , args . base_low , args . base_high , not args . no_noise )
52 if args . webcam :
53 pr ocess_we bcam ( args . cam_index , args . seed , args . base_low , args . base_high , not args .
no_noise , args . width , args . height , args . fps )
54
55 if __name__ == " __main__ " :
56 main ()
Listing 2. Webcam y Main