Imagina que estás trabajando en tus proyectos de OpenCV, cuando de pronto alguien desesperado por tu ayuda te dice: mira tengo unas imágenes y quiero que los rostros que aparezcan dentro de cada una de ellas sean borrados, por aquello de la privacidad y necesito poder variar el grado de borrosidad para ver cual queda mejor. Además es necesario que las imágenes puedan mostrarse a color y a escala de grises.
Después de haber escuchado todo esto, tú te preguntas como mostrarle todo esto a ese usuario, porque no podrías estar ejecutando, finalizando y cambiando el valor de las variables dentro del programa a cada momento, ya que se perdería la percepción de los efectos de borrosidad. Otra opción sería guardar varias imágenes con los distintos niveles de borrosidad y en escala de grises, pero no sería eficiente en este caso. Finalmente recuerdas que alguna vez viste que se podía incrustar una barra deslizante a las imágenes con OpenCV, y de hecho esta es una muy buena idea.
En este tutorial vamos a ver precisamente eso, el realizar una aplicación en la cual deberemos a través del control de una barra deslizante, dar distintos niveles de borrosidad a los rostros que estén dentro de una imagen, además podremos mostrarla a color o grises. Finalmente veremos como realizar este proceso en un video streaming.
CONTENIDO:
- ¿Qué es trackbar o barra deslizante (control deslizante / control de rango) en OpenCV?
- ¿Cómo crear y obtener el valor de un trackbar / barra deslizante en OpenCV?
- cv2.createTrackbar
- cv2.getTrackbarPos
- ¿Cómo crear y obtener el valor de un trackbar / barra deslizante en OpenCV?
- Empecemos con la aplicación sobre una imagen
- Creando los trackbar / barra deslizante
- Obteniendo las posiciones de las barras de seguimiento
- ¿A color o a escala de grises?
- Detectando rostros y haciéndolos borrosos
- Finalmente…
- Programa completo
- Resultados
- Empleando esta aplicación sobre un video streaming
- Resultados
La detección de rostros que vamos a utilizar en el tutorial del hoy ya la he explicado antes, por lo que si quieres un tutorial más completo sobre ello visita: ? DETECCIÓN DE ROSTROS ? con Haar Cascades Python – OpenCV.
¿Qué es trackbar o barra deslizante (control deslizante / control de rango) en OpenCV?

Figura 1: Visualización de la barra deslizante (trackbar).
OpenCV ofrece algunas herramientas GUI (Interfaz Gráfica de Usuario) para integrarlas dentro de nuestras aplicaciones. Una de ellas es trackbar o barra deslizante, que podrá ser controlada por el usuario mediante el movimiento de una «perilla», de tal modo que variará el valor de cierto parámetro entero, mientras la aplicación se está ejecutando.
¿Cómo crear y obtener el valor de un trackbar / barra deslizante en OpenCV?
Para crear el control deslizante se necesita de la función cv2.createTrackbar mientras que para obtener el valor correspondiente a posición de esta barra de seguimiento se necesita de cv2.getTrackbarPos. Veamos como usar cada una de estas dos funciones:
cv2.createTrackbar

Figura 2: Barra deslizante (winnname y trackbarname).
Según nos explica OpenCV, esta función crea una barra de seguimiento/ control deslizante/control de rango y la adjunta a una ventana con un nombre específico.
Parámetros:
- trackbarname, nombre de la barra de seguimiento creada.
- winname, nombre de la ventana que será usada como padre de la barra de seguimiento creada.
- value, puntero opcional a una variable entera cuyo valor refleja la posición del slider (control deslizante). Después de la creación, la posición del slider es definida por esta variable.
- count, posición máxima del slider. La posición mínima siempre será cero.
- onChange, puntero a la función a llamar cada vez que el slider cambia su pocisión.
Recuerda visitar la documentación de OpenCV para más información.
cv2.getTrackbarPos
Esta retorna la posición de la barra de seguimiento.
Parámetros:
- trackbarname, nombre de la barra de seguimiento creada.
- winname, nombre de la ventana que será usada como padre de la barra de seguimiento creada.
1. Empecemos con la aplicación sobre una imagen
La imagen con la que vamos a trabajar en esta ocasión es la siguiente:

Figura 3: Imagen de entrada
import cv2 def nothing(x): pass image = cv2.imread('oficina.jpeg') faceClassif = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') cv2.namedWindow('Imagen')
Línea 1: Importamos OpenCV.
Línea 3 y 4: Creamos una función llamada nothing
que nos servirá como parámetro para crear el trackbar. De hecho esta función no hará ninguna operación, simplemente servirá como auxiliar en este caso. Tú podrías desarrollar en vez de esta función otra con operaciones que dependan del valor x
que corresponde al cambio de posición de la barra deslizante.
Línea 6: Leemos la imagen de entrada.
Línea 7: Llamamos al clasificador de rostros pre entrenado haar cascade. Recuerda que el archivo haarcascade_frontalface_default.xml
debe estar en la misma carpeta en donde está guardado el script donde estás desarrollando este programa. Si tienes alguna duda sobre como se realiza el proceso de detección de rostros te recomiendo que visites el post anterior.
Línea 8: Especificamos el nombre de la ventana en donde se va a visualizar la imagen, en este caso el nombre que se ha asignado es 'Imagen'
.
1.1 Creando los trackbar / barra deslizante
cv2.createTrackbar('Blur','Imagen',0,15,nothing) cv2.createTrackbar('Gray','Imagen',0,1,nothing)
Línea 9: Vamos a crear la barra deslizante correspondiente a la borrosidad o difuminado. Para ello estableceremos el nombre del trackbar 'Blur'
, el nombre de la ventana 'Imagen'
que habíamos especificado en la línea 8. En cuanto al parámetro value se ha puesto 0, que quiere decir que en un principio el slider va a estar ubicado en 0. El valor máximo será 15
pero podrías probar con otros valores, y finalmente llamamos a la función que habíamos creado en un principio nothing
.
NOTA: En el parámetro value, tú podrías ajustarlo en algún entero mayor a 0 por ejemplo, esto querría decir que en un principio la posición tomaría ese valor. Sin embargo ten en cuenta que el valor mínimo siempre será 0.
Línea 10: Este será el segundo trackbar correspondiente a mostrar la imagen a color o escala de grises. Seguimos el mismo procedimiento que la anterior línea, las diferencias estarán en que en el parámetro trackbarname será 'Gray'
y en count 1
. Lo que quiere decir que si se mantiene en 0 se mostrará la imagen a color, mientras que si está en 1 se mostrará en escala de grises.
1.2 Obteniendo las posiciones de las barras de seguimiento
while True: val = cv2.getTrackbarPos('Blur','Imagen') grayVal = cv2.getTrackbarPos('Gray','Imagen')
Línea 12: Vamos por el ciclo while, que nos permitirá realizar el proceso indefinidamente hasta que una tecla sea presionada.
Línea 14: Para obtener el valor de la posición de la barra deslizante necesitamos de cv2.getTrackbarPos
, en ella se debe especificar el nombre del trackbar en este caso 'Blur'
y el nombre de la ventana en donde se mostrará, en este caso 'Imagen'
. Este valor se almacenará enval
.
Línea 15: Ahora es el turno de la segunda barra de control deslizante. Debemos especificar 'Gray'
como su nombre, mientras que al igual que la anterior barra 'Imagen'
para el nombre de la ventana, ya que ambas barras se mostrarán en la misma. El valor de la posición se almacenará en grayVal
.
Ahora que tenemos las posiciones almacenadas en variables podremos usarlas como cualquier variable entera, veamos:
1.2.1 ¿A color o a escala de grises?
Recordemos que el trackbar que establecimos para indicar si una imagen se muestra a color o escala de grises puede tomar dos valores 0 o 1.
if grayVal == 1: imageN = cv2.cvtColor(image.copy(), cv2.COLOR_BGR2GRAY) else: imageN = image.copy()
Línea 16: Vamos con la condición si grayVal == 1
eso quiere decir que la imagen debe mostrarse a escala de grises, caso contrario a colores.
Línea 17: Si se cumple con la condición de la línea 16 entonces debe mostrarse la imagen en escala de grises, para ello debemos usar la función cv2.cvtColor
.
Línea 18: Si grayVal
es 0, entonces la imagen será la misma que la entrada.
NOTA: Toma en cuenta que tanto en la línea 17 y 18 he usado image.copy()
esto para que se tome en todo momento la imagen de entrada. Si quitáramos la extensión .copy()
se estaría llamando a una imagen modificada por cada iteración.
1.2.2 Detectando rostros y haciéndolos borrosos
Es hora de detectar los rostros presentes en la imagen de entrada y difuminarlos a distinto grado.
faces = faceClassif.detectMultiScale(image, 1.1, 5) for (x,y,w,h) in faces: if val > 0: imageN[y:y+h,x:x+w] = cv2.blur(imageN[y:y+h,x:x+w],(val,val))
Línea 19: En faces
se almacenarán todos los rostros encontrados.
Línea 21: Ahora procedemos a desempaquetar la información de faces
que son las coordenadas x
e y
en donde se encuentran rostros, además de su ancho y alto.
Línea 22 y 23: Si val > 0
entonces se procederá a aplicar cv2.blur
en el área en donde se encuentre el rostro. Por cierto se establece un valor mayor a 0, ya que si usamos 0 en cv2.blur
obtendremos un error. Además de este modo podremos comparar las imágenes al no tener ningún grado de borrosidad y cuando este incrementa. Si deseas más información sobre esta función usada para difuminar visita la documentación de OpenCV.
1.3 Finalmente…
cv2.imshow('Imagen',imageN) k = cv2.waitKey(1) if k == 27: break cv2.destroyAllWindows()
Línea 25: Visualizamos la imagen.
Línea 26 a 28: El proceso se detendrá hasta que sea presionada la tecla ‘Esc’.
Línea 29: Se cierran todas las ventanas creadas.
1.4 Programa completo
import cv2 def nothing(x): pass image = cv2.imread('oficina.jpeg') faceClassif = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') cv2.namedWindow('Imagen') cv2.createTrackbar('Blur','Imagen',0,15,nothing) cv2.createTrackbar('Gray','Imagen',0,1,nothing) while True: val = cv2.getTrackbarPos('Blur','Imagen') grayVal = cv2.getTrackbarPos('Gray','Imagen') if grayVal == 1: imageN = cv2.cvtColor(image.copy(), cv2.COLOR_BGR2GRAY) else: imageN = image.copy() faces = faceClassif.detectMultiScale(image, 1.1, 5) for (x,y,w,h) in faces: if val > 0: imageN[y:y+h,x:x+w] = cv2.blur(imageN[y:y+h,x:x+w],(val,val)) cv2.imshow('Imagen',imageN) k = cv2.waitKey(1) if k == 27: break cv2.destroyAllWindows()
1.5 Resultados
A continuación vamos a ver algunas pruebas realizadas con el programa que hemos desarrollado, veamos:
En la visualización nos podemos dar cuenta que los rostros sen han detectado y conforme cambiamos la posición en ‘Blur’, la borrosidad o difuminado se hace más evidente.
En cuanto a ‘Gray’, también podemos visualizar que si se mantiene en 0, la imagen se muestra a color mientras que si cambia a 1 se visualiza en escala de grises.
2. Empleando esta aplicación sobre un video streaming
A continuación te podrás dar cuenta que el proceso es prácticamente el mismo.
import cv2 def nothing(x): pass cap = cv2.VideoCapture(0) faceClassif = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') cv2.namedWindow('frame') cv2.createTrackbar('Blur','frame',0,15,nothing) cv2.createTrackbar('Gray','frame',0,1,nothing) while True: ret,frame = cap.read() val = cv2.getTrackbarPos('Blur','frame') grayVal = cv2.getTrackbarPos('Gray','frame') if grayVal == 1: frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = faceClassif.detectMultiScale(frame, 1.3, 5) for (x,y,w,h) in faces: if val > 0: frame[y:y+h,x:x+w] = cv2.blur(frame[y:y+h,x:x+w],(val,val)) cv2.imshow('frame',frame) k = cv2.waitKey(1) & 0xFF if k == 27: break cap.release() cv2.destroyAllWindows()
La diferencia está (aparte de que se está leyendo una secuencia de imágenes y ya no una sola) en que ya no es necesario usar .copy()
, puesto que en cada momento se está tomando una nueva imagen.
2.1 Resultados
Y bien esto ha sido todo por este tutorial. Logramos solucionar el problema que en un principio se había planteado. Si deseas puede dejar algún comentario, sugenrencia o corrección y ¡sigamos aprendiendo juntos!.
Eres increíble mi Gaby!!! ? Súper bueno el tutorial.. muy bien explicado!
Muchas gracias Brendita, te quiero mucho 🙂
Hola! estoy aprendiendo mucho de tus articulos y videos.
Algunas de estas aplicaciones las querría implementar en mi raspberry pi
pero no consigo importar opencv en ese ordenador.
en los demás me funciona bien.
pero en raspberry me sale » undefined symbol __atomic_fetch_add_8″
te suena como resolver eso?
gracias de antemano
Hola Fernando muchas gracias por comentar. En realidad no había obtenido ese error, pero te dejo estos links en donde hablan de ello y dan algunas soluciones, espero que sea de ayuda: https://github.com/piwheels/packages/issues/59 https://github.com/EdjeElectronics/TensorFlow-Object-Detection-on-the-Raspberry-Pi/issues/67
Hola Gabi ,
Primero felicitarte por tu trabajo, esta muy bien explicado, por lo que ayuda a entender los procesos de tratamientos de imagen etc.
Segundo, hace poco me estoy iniciando a la detección de objetos mediante opencv y python, quería tratar el tema de detección de objetos, no solo figura poligonales, mediante imágenes de muestra o librería. La información que veo por la web no me despeja el camino o que técnica a seguir.
¿tu conoces algún sitio para entender mejor el proceso, tipo técnica, libro o ejemplo?
Gracias por atenderme y gracias puedas o no puedas pasarme información
Edu
Hola Eduardo, me parece que lo que necesitas es usar machine learning, para que puedas realizar la detección de objetos dada una base de datos donde estén los objetos que deseas detectar e imágenes donde no estén. Puedes visitar la página de coursera, allí solía haber un curso gratuito sobre detección de objetos en español, realizado por una universidad de España.