Crear Air Canvas usando Python-OpenCV

Alguna vez quisiste dibujar tu imaginación simplemente moviendo tu dedo en el aire. En esta publicación, aprenderemos a construir un Air Canvas que puede dibujar cualquier cosa con solo capturar el movimiento de un marcador de color con una cámara. Aquí se utiliza como marcador un objeto coloreado en la punta del dedo.
Usaremos las técnicas de visión por computadora de OpenCV para construir este proyecto. El lenguaje preferido es Python debido a sus bibliotecas exhaustivas y su sintaxis fácil de usar, pero al comprender los conceptos básicos, se puede implementar en cualquier lenguaje compatible con OpenCV.
Aquí se utilizan la detección de color y el seguimiento para lograr el objetivo. Se detecta el marcador de color y se produce una máscara. Incluye los pasos posteriores de las operaciones morfológicas sobre la máscara producida, que son Erosión y Dilatación. La erosión reduce las impurezas presentes en la máscara y la dilatación restaura aún más la máscara principal erosionada.
Requisitos: 
 

Algoritmo: 
 

  1. Comience a leer los cuadros y convierta los cuadros capturados al espacio de color HSV (Fácil para la detección de color). 
     
  2. Prepara el marco del lienzo y ponle los respectivos botones de tinta. 
     
  3. Ajuste los valores de la barra de seguimiento para encontrar la máscara del marcador de color. 
     
  4. Preprocesar la máscara con operaciones morfológicas (Erosión y dilatación). 
     
  5. Detecte los contornos, encuentre las coordenadas centrales del contorno más grande y siga almacenándolos en la array para fotogramas sucesivos (Arrays para dibujar puntos en el lienzo). 
     
  6. Finalmente, dibuje los puntos almacenados en una array en los marcos y el lienzo.
     

A continuación se muestra la implementación.
 

Python3

import numpy as np
import cv2
from collections import deque
 
  
# default called trackbar function
def setValues(x):
   print("")
  
 
# Creating the trackbars needed for
# adjusting the marker colour These
# trackbars will be used for setting
# the upper and lower ranges of the
# HSV required for particular colour
cv2.namedWindow("Color detectors")
cv2.createTrackbar("Upper Hue", "Color detectors",
                   153, 180, setValues)
cv2.createTrackbar("Upper Saturation", "Color detectors",
                   255, 255, setValues)
cv2.createTrackbar("Upper Value", "Color detectors",
                   255, 255, setValues)
cv2.createTrackbar("Lower Hue", "Color detectors",
                   64, 180, setValues)
cv2.createTrackbar("Lower Saturation", "Color detectors",
                   72, 255, setValues)
cv2.createTrackbar("Lower Value", "Color detectors",
                   49, 255, setValues)
 
 
# Giving different arrays to handle colour
# points of different colour These arrays
# will hold the points of a particular colour
# in the array which will further be used
# to draw on canvas
bpoints = [deque(maxlen = 1024)]
gpoints = [deque(maxlen = 1024)]
rpoints = [deque(maxlen = 1024)]
ypoints = [deque(maxlen = 1024)]
  
# These indexes will be used to mark position
# of pointers in colour array
blue_index = 0
green_index = 0
red_index = 0
yellow_index = 0
  
# The kernel to be used for dilation purpose
kernel = np.ones((5, 5), np.uint8)
 
# The colours which will be used as ink for
# the drawing purpose
colors = [(255, 0, 0), (0, 255, 0),
          (0, 0, 255), (0, 255, 255)]
colorIndex = 0
  
# Here is code for Canvas setup
paintWindow = np.zeros((471, 636, 3)) + 255
  
cv2.namedWindow('Paint', cv2.WINDOW_AUTOSIZE)
  
 
# Loading the default webcam of PC.
cap = cv2.VideoCapture(0)
  
# Keep looping
while True:
     
    # Reading the frame from the camera
    ret, frame = cap.read()
     
    # Flipping the frame to see same side of yours
    frame = cv2.flip(frame, 1)
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
  
    # Getting the updated positions of the trackbar
    # and setting the HSV values
    u_hue = cv2.getTrackbarPos("Upper Hue",
                               "Color detectors")
    u_saturation = cv2.getTrackbarPos("Upper Saturation",
                                      "Color detectors")
    u_value = cv2.getTrackbarPos("Upper Value",
                                 "Color detectors")
    l_hue = cv2.getTrackbarPos("Lower Hue",
                               "Color detectors")
    l_saturation = cv2.getTrackbarPos("Lower Saturation",
                                      "Color detectors")
    l_value = cv2.getTrackbarPos("Lower Value",
                                 "Color detectors")
    Upper_hsv = np.array([u_hue, u_saturation, u_value])
    Lower_hsv = np.array([l_hue, l_saturation, l_value])
  
  
    # Adding the colour buttons to the live frame
    # for colour access
    frame = cv2.rectangle(frame, (40, 1), (140, 65),
                          (122, 122, 122), -1)
    frame = cv2.rectangle(frame, (160, 1), (255, 65),
                          colors[0], -1)
    frame = cv2.rectangle(frame, (275, 1), (370, 65),
                          colors[1], -1)
    frame = cv2.rectangle(frame, (390, 1), (485, 65),
                          colors[2], -1)
    frame = cv2.rectangle(frame, (505, 1), (600, 65),
                          colors[3], -1)
     
    cv2.putText(frame, "CLEAR ALL", (49, 33),
                cv2.FONT_HERSHEY_SIMPLEX, 0.5,
                (255, 255, 255), 2, cv2.LINE_AA)
     
    cv2.putText(frame, "BLUE", (185, 33),
                cv2.FONT_HERSHEY_SIMPLEX, 0.5,
                (255, 255, 255), 2, cv2.LINE_AA)
     
    cv2.putText(frame, "GREEN", (298, 33),
                cv2.FONT_HERSHEY_SIMPLEX, 0.5,
                (255, 255, 255), 2, cv2.LINE_AA)
     
    cv2.putText(frame, "RED", (420, 33),
                cv2.FONT_HERSHEY_SIMPLEX, 0.5,
                (255, 255, 255), 2, cv2.LINE_AA)
     
    cv2.putText(frame, "YELLOW", (520, 33),
                cv2.FONT_HERSHEY_SIMPLEX, 0.5,
                (150, 150, 150), 2, cv2.LINE_AA)
  
  
    # Identifying the pointer by making its
    # mask
    Mask = cv2.inRange(hsv, Lower_hsv, Upper_hsv)
    Mask = cv2.erode(Mask, kernel, iterations = 1)
    Mask = cv2.morphologyEx(Mask, cv2.MORPH_OPEN, kernel)
    Mask = cv2.dilate(Mask, kernel, iterations = 1)
  
    # Find contours for the pointer after
    # identifying it
    cnts, _ = cv2.findContours(Mask.copy(), cv2.RETR_EXTERNAL,
        cv2.CHAIN_APPROX_SIMPLE)
    center = None
  
    # Ifthe contours are formed
    if len(cnts) > 0:
         
        # sorting the contours to find biggest
        cnt = sorted(cnts, key = cv2.contourArea, reverse = True)[0]
         
        # Get the radius of the enclosing circle
        # around the found contour
        ((x, y), radius) = cv2.minEnclosingCircle(cnt)
         
        # Draw the circle around the contour
        cv2.circle(frame, (int(x), int(y)), int(radius), (0, 255, 255), 2)
         
        # Calculating the center of the detected contour
        M = cv2.moments(cnt)
        center = (int(M['m10'] / M['m00']), int(M['m01'] / M['m00']))
  
        # Now checking if the user wants to click on
        # any button above the screen
        if center[1] <= 65:
             
            # Clear Button
            if 40 <= center[0] <= 140:
                bpoints = [deque(maxlen = 512)]
                gpoints = [deque(maxlen = 512)]
                rpoints = [deque(maxlen = 512)]
                ypoints = [deque(maxlen = 512)]
  
                blue_index = 0
                green_index = 0
                red_index = 0
                yellow_index = 0
  
                paintWindow[67:, :, :] = 255
            elif 160 <= center[0] <= 255:
                    colorIndex = 0 # Blue
            elif 275 <= center[0] <= 370:
                    colorIndex = 1 # Green
            elif 390 <= center[0] <= 485:
                    colorIndex = 2 # Red
            elif 505 <= center[0] <= 600:
                    colorIndex = 3 # Yellow
        else :
            if colorIndex == 0:
                bpoints[blue_index].appendleft(center)
            elif colorIndex == 1:
                gpoints[green_index].appendleft(center)
            elif colorIndex == 2:
                rpoints[red_index].appendleft(center)
            elif colorIndex == 3:
                ypoints[yellow_index].appendleft(center)
                 
    # Append the next deques when nothing is
    # detected to avois messing up
    else:
        bpoints.append(deque(maxlen = 512))
        blue_index += 1
        gpoints.append(deque(maxlen = 512))
        green_index += 1
        rpoints.append(deque(maxlen = 512))
        red_index += 1
        ypoints.append(deque(maxlen = 512))
        yellow_index += 1
  
    # Draw lines of all the colors on the
    # canvas and frame
    points = [bpoints, gpoints, rpoints, ypoints]
    for i in range(len(points)):
         
        for j in range(len(points[i])):
             
            for k in range(1, len(points[i][j])):
                 
                if points[i][j][k - 1] is None or points[i][j][k] is None:
                    continue
                     
                cv2.line(frame, points[i][j][k - 1], points[i][j][k], colors[i], 2)
                cv2.line(paintWindow, points[i][j][k - 1], points[i][j][k], colors[i], 2)
  
    # Show all the windows
    cv2.imshow("Tracking", frame)
    cv2.imshow("Paint", paintWindow)
    cv2.imshow("mask", Mask)
  
    # If the 'q' key is pressed then stop the application
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break
 
# Release the camera and all resources
cap.release()
cv2.destroyAllWindows()

Producción: 
 

Sample project screenshot

Publicación traducida automáticamente

Artículo escrito por infoaryan y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *