Uso del mouse y trackbar OpenCV

El mouse y el trackbar son componentes de la GUI que nos ayudarán a interactuar con la aplicación OpenCV que estemos desarrollando, esta la biblioteca nos permite agregar manejadores de eventos para responder a eventos del ratón, de igual manera podemos agregar una barra desplazable a una ventana y obtener el valor de la misma.

Programación con trackbar

Para agregar este elemento a una ventana usamos la función cv2.createTrackbar() debemos indicarle el titulo o etiqueta que mostrará, el nombre de la ventana a la que pertenece, el valor actual, el valor máximo y la función callback que será llamada cada vez que se cambie el valor del control.

title = 'Drawing'

cv2.namedWindow(title)
cv2.createTrackbar('Grosor', title, 5, 50, on_trackbar)

La función on_trackbar se define como sigue:

def on_trackbar(value):
    print(value)

Este pequeño ejemplo imprime el valor actual del control, otra forma de obtener el valor es usando la función cv2.getTrackbarPos('Grosor', 'Drawing') primero indicamos el nombre del trackbar y luego la ventana en la que se encuentra, el valor devuelto por esta función corresponde al valor del control indicado.

Programación con el ratón

Para agregar un manejador de eventos para el mouse usamos la función cv2.setMouseCallback() el primer parámetro es el nombre de la ventana, seguido de la función callback y luego opcionalmente podemos enviar un parámetro cualquiera a la función callback, por ejemplo una imagen, de este modo evitamos usar variables globales.

title = 'Drawing'
image = np.zeros((600, 800, 3), np.uint8)
    
cv2.namedWindow(title)
cv2.setMouseCallback(title, on_mouse, image)

La función on_mouse es invocada cada vez que se produce un evento del mouse, esta función tiene la siguiente forma:

def on_mouse(event, x, y, flags, param):

    global start
    pt = (x, y)

    if event == cv2.EVENT_LBUTTONDOWN:
        start = True
    elif event == cv2.EVENT_LBUTTONUP:
        start = False
    elif start and event == cv2.EVENT_MOUSEMOVE:
        ventana = 'Drawing'
        grosor = cv2.getTrackbarPos('Grosor', ventana)

        cv2.circle(param, pt, grosor, (255, 0, 255), -1)

En esta función x, y contienen la posición actual del mouse, param hace referencia al parámetro opcional enviado desde la función principal.

El evento se identifica mediante event y puede tener los siguientes valores:

  • EVENT_MOUSEMOVE movimiento del mouse
  • EVENT_LBUTTONDOWN botón izquierdo presionado
  • EVENT_RBUTTONDOWN botón derecho presionado
  • EVENT_MBUTTONDOWN botón central presionado
  • EVENT_LBUTTONUP botón izquierdo liberado
  • EVENT_RBUTTONUP botón derecho liberado
  • EVENT_MBUTTONUP botón central liberado
  • EVENT_LBUTTONDBLCLK doble clic izquierdo
  • EVENT_RBUTTONDBLCLK doble clic derecho
  • EVENT_MBUTTONDBLCLK doble clic central
  • EVENT_MOUSEWHEEL giro de la rueda vertical
  • EVENT_MOUSEHWHEEL giro de la rueda horizontal

La variable flags nos proporciona la siguiente información:

  • EVENT_FLAG_LBUTTON el botón izquierdo está presionado
  • EVENT_FLAG_RBUTTON el botón derecho está presionado
  • EVENT_FLAG_MBUTTON el botón central está presionado
  • EVENT_FLAG_CTRLKEY la tecla Ctrl está presionada
  • EVENT_FLAG_SHIFTKEY la tecla Shift está presionada
  • EVENT_FLAG_ALTKEY la tecla Alt está presionada

Pintar con el mouse

Para la demostración de la teoría explicada crearemos una aplicación que nos permite pintar usando los movimiento del mouse, usaremos el trackbar para definir el grosor del pincel.

Para dibujar debemos mantener presionado el botón izquierdo y movernos sobre el área que deseamos pintar, para hacer esto simplemente dibujamos un circulo del grosor indicado en el trackbar y la posición definida por el movimiento del mouse. 

import cv2
import numpy as np

start = False

def on_trackbar(value):
    pass

def on_mouse(event, x, y, flags, param):

    global start
    pt = (x, y)

    if event == cv2.EVENT_LBUTTONDOWN:
        start = True
    elif event == cv2.EVENT_LBUTTONUP:
        start = False
    elif start and event == cv2.EVENT_MOUSEMOVE:
        ventana = 'Drawing'
        grosor = cv2.getTrackbarPos('Grosor', ventana)

        cv2.circle(param, pt, grosor, (255, 0, 255), -1)

if __name__ == "__main__":

    title = 'Drawing'
    image = np.zeros((600, 800, 3), np.uint8)
    
    cv2.namedWindow(title)
    cv2.createTrackbar('Grosor', title, 5, 50, on_trackbar) 
    cv2.setMouseCallback(title, on_mouse, image)

    while(1):
        cv2.imshow(title, image)
        if cv2.waitKey(20) & 0xFF == 27:
            break
        
    cv2.destroyAllWindows()

Si ejecutamos, el resultado es:

Dibujar con el mouse

La función que usamos para dibujar es cv2.circle(...) puedes ver todas las funciones de dibujo proporcionadas por OpenCV en dicho tutorial.

Como tarea puedes agregar tres controles más para definir el color del pincel, los tres controles corresponden a los canales BGR del color.

Comentarios

Entradas populares de este blog

Conectar SQL Server con Java

Entrenar OpenCV en Detección de Objetos

Detección de figuras geométricas

Procesamiento de imágenes en OpenCV

Conociendo la clase cv::Mat de OpenCV