35

Interacción entre OpenCV y Arduino con pySerial

portada

Si eres alguno de nuestros lectores habituales habrás notado que últimamente se me ha dado por escribir tutoriales y guías de OpenCV. Hoy voy a explicar cómo se puede comunicar una placa Arduino y controlarla mediante OpenCV. Más concretamente, voy a reciclar el código de mi tutorial de detección de colores y, cada vez que la cámara vea un objeto verde, se encenderá el led 13 de la placa Arduino.

Para ello utilizaremos la librería Pyserial para poder enviar comandos por serial con python a Arduino.

Y pondremos un poco de música, por supuesto.

Supondré que tienes instalado OpenCV y conoces algunas de sus funciones básicas. Además, necesitarás saber cómo funciona la IDE de Arduino y como programarla.


¿Por qué utilizar Arduino para controlar actuadores?

Si planeamos construir un robot que deba realizar cálculos complejos (como es el caso de la visión por computador) Arduino se nos queda corta.

Por esa razón, es mejor delegar el grueso de nuestros cálculos a una SBC como puede ser Raspberry Pi u otras más potentes (Wandboard, Odroid, etc). Muchas de estas placas disponen de pines GPIO para controlar actuadores, pero mi experiencia me dice que en muchas ocasiones son difíciles de configurar (si habéis intentado controlar un servo con Raspberry Pi ya sabéis de qué hablo). Sin embargo, Arduino nos permite controlar estos actuadores muy fácilmente, de forma que es una buena idea conectarla a nuestra SBC para que reciba instrucciones vía USB.

sbc

Hay muchas SBCs diferentes

Acerca de Pyserial

pySerial es una librería que permite enviar comandos, strings y información variada por Serial. Utilizar esta librería es la forma más sencilla que tenemos para enviar los datos de OpenCV a la placa Arduino.

pySerial viene por defecto con la última versión de Python, pero si por alguna extraña razón no la tienes y estás en Linux (Ubuntu, Debian o una distribución con sistema de paquetes .deb), abre la Terminal y escribe:

sudo apt-get install python-serial

Tutorial

Necesitamos:

  1. Ordenador con OpenCV y Arduino IDE instalados
  2. Placa Arduino y Cable USB. Cualquier modelo de Arduino valdrá.
  3. Webcam configurada y funcional

Comenzamos escribiendo el código para Arduino. Es muy sencillo: si recibe ‘h’ por serial se enciende el pin 13, si no, se apaga. Puedes conectar un LED exterior al pin 13 si lo prefieres.


/*
Interaccion entre Arduino y OpenCV
Codigo para Arduino

Por Glar3
*/

#define LED 13
char lectura; //Variable para guardar la lectura del Serial

void setup()
{
   //Iniciamos el Serial:
   Serial.begin(9600);

   //Inicializamos el pin 13
   pinMode(LED, OUTPUT);
}

void loop()
{
   //Si recibimos algo por serial, lo guardamos
   if(Serial.available() >= 1)
   {
      lectura = Serial.read();

      //-Si recibiste 'h' -> enciende LED
      //-Si recibiste otro caracter -> apaga el LED
      if(lectura == 'h')
      {
         digitalWrite(LED, HIGH);
      }
      else
      {
         digitalWrite(LED, LOW);
      }
   }
}

El código de OpenCV, como ya he dicho, es una variación del que escribí en el tutorial de detección de colores. Buscará un objeto verde y si este tiene un cierto tamaño, se envía el carácter ‘h’ por Serial. Si no, se envía ‘n’.

Si quieres entender cómo funciona el código de detección de colores deberías leer el tutorial original.


#Codigo de interaccion entre Arduino y OpenCV
#Por Glar3

import cv2
import numpy as np
import serial #cargamos la libreria serial

#Iniciamos la camara
captura = cv2.VideoCapture(0)

#Iniciamos la comunicacion serial
ser = serial.Serial('/dev/ttyUSB0', 9600)

while(1):

   #Capturamos una imagen y la convertimos de RGB -> HSV
   _, imagen = captura.read()
   hsv = cv2.cvtColor(imagen, cv2.COLOR_BGR2HSV)

   #Establecemos el rango de colores que vamos a detectar
   #En este caso de verde oscuro a verde-azulado claro
   verde_bajos = np.array([49,50,50], dtype=np.uint8)
   verde_altos = np.array([80, 255, 255], dtype=np.uint8)

   #Crear una mascara con solo los pixeles dentro del rango de verdes
   mask = cv2.inRange(hsv, verde_bajos, verde_altos)

   #Encontrar el area de los objetos que detecta la camara
   moments = cv2.moments(mask)
   area = moments['m00']

   #Descomentar para ver el area por pantalla
   #print area

   #Si el objeto tiene un area determinada, escribimos 'h'
   #Si no, escribimos un caracter erroneo
   if(area > 2000000):
      ser.write('h')

   else:
      ser.write('n')

   #Mostramos la imagen original y
   #la mascara
   cv2.imshow('mask', mask)
   cv2.imshow('Camara', imagen)
   tecla = cv2.waitKey(5) & 0xFF
   if tecla == 27:
      break

cv2.destroyAllWindows()

¡Recuerda cambiar la dirección ‘/dev/ttyUSB0’ de la línea 12 por la dirección de tu Arduino! Si estás en linux seguramente no tendrás que cambiarla, y si estás en Windows será ‘COM3’ o un nombre parecido.

Y esto es todo por hoy. Si has seguido todos los pasos debería encenderse el LED 13 de Arduino cada vez que la cámara detecta un objeto de color verde. Si no te funciona, revisa el código. También puedes dejarme tus dudas en los comentarios y te responderé en cuánto pueda.

Por otra parte, si te sirvió este tutorial también puedes agradecérmelo. ¡Estaré contenta!

Gl4r3

Brillante, luminosa y cegadora a veces, Glare es tan artista como técnica. Le encanta dar rienda suelta a sus módulos de imaginación y desdibujar los ya de por si delgados límites que separan el mundo de la electrónica y el arte. Su mayor creación hasta la fecha es un instrumento capaz de convertir los colores y la luz en música. Cuándo sus circuitos no están trabajando en una nueva obra electrónica, le gusta dedicar sus ciclos a la lectura o a documentar sus invenciones para beneficio de los humanos. Sus artilugios favoritos son aquellos que combinan una funcionalidad práctica con un diseño elegante y artístico.

Antes de comentar, por favor, lee las Normas

35 Comentarios en "Interacción entre OpenCV y Arduino con pySerial"

avatar
Ordenar por:   más nuevos primero | más antiguos primero
pole
Humano

hola! en visual studio community 2017 cambiaría mucho el código? no funciona ni lo primero!!!
import cv2
import numpy as np

pole
Humano

perdón en 2015 quería decir…

pole
Humano

vale genial es que no veía el open cv… es decir que se me ha desinstalado todo y lo he retomado desde hace meses y no puedo abrir open cv …. antes sí que me funcionaba

Mauricio
Humano

Para todos los que se les queda encendido el led, es por que ocupan establecer bien la comunicación serial, para ello se ocupa un tiempo de espera depués de declarar la comunicación establecida.

————————————-
import time

ser = serial.Serial(‘COM6’, baudrate = 9600, timeout = 1)
time.sleep(4) #Genera un delay de 4 segundos (Puede ser distinto el tiempo)

————————————-

Pongan eso en vez de lo que se tiene en el código original suministrado por esta página.

jhon
Humano

gracias por el tutorial, agradecimientos desde Colombia. Muy bien explicado

Aun que tendría una duda, ¿como se aria, para que el sistema de reconocimiento de colores detecte no una si no varias cámaras con varios LED´s?

Joel
Humano

hola glare estoy haciendo un brazo robot con servos que selecciona objetos verdes, pero cuando la camara detecta el verde hace la misma secuencia de movimientos una y otra vez, mientras mas tiempo se quede el objeto verde en la camara mas secuencias hace, lo que quisiera es q solo lo haga una sola secuencia cada vez q detecta verde ¿que puede estar mal?… gracias

fernando
Humano

antes que todo quisiera agradecer por el excelente trabajo.

luego de seguir el tutorial no consigo que el led de arduino se apague. al momento de iniciar el proyecto el led se enciende hasta que detengo el proyecto. y lo ultimo quisiera saber si en la linea 17 esta expresión _, debe de ser reemplazada por algo?

desde ya un caluroso saludo

Josdavjr
Humano

Digamos que obtengo los centros de el objeto capturado como envío los valores x e y por el serial???
Muchas gracias por tu aporte eres genial!!!!!

Marcos Moreira
Humano
hola amigo, gracias pero hice un cambio en el fichero python (para que funcione correrlo en termina) 🙂 #Codigo de interaccion entre Arduino y OpenCV #Por Glar3 import cv2 import numpy as np import serial #cargamos la libreria serial #Iniciamos la camara captura = cv2.VideoCapture(0) #Iniciamos la comunicacion serial ser = serial.Serial(‘/dev/ttyACM0’, 9600) while(1): #Capturamos una imagen y la convertimos de RGB -> HSV _, imagen = captura.read() hsv = cv2.cvtColor(imagen, cv2.COLOR_BGR2HSV) #Establecemos el rango de colores que vamos a detectar #En este caso de verde oscuro a verde-azulado claro verde_bajos = np.array([49,50,50], dtype=np.uint8) verde_altos = np.array([80, 255, 255], dtype=np.uint8)… Leer más »
Alain Vega Labrada
Humano

Disculpa no se como modificar lo anterior al parar el programa de Python se apaga Rx y Led permanente encendido. Al iniciarlo Led y Rx permanente encendidos. El Reset apaga el led. Y así no hay forma que funcione luego de presionar el Esc en la primera corrida luego de reconectar todo.

Alain Vega Labrada
Humano
Hoy reconecte todo de nuevo a la pc y corri el código tal y como lo tienes solo cambiando “ser = serial.Serial(‘/dev/ttyUSB0’, 9600)” por “ser = serial.Serial(‘COM’, 9600)”. Todo funciona bien si pongo algo verde enciende si lo quito se apaga. Retiro el verde y presiono Esc y de nuevo mas nunca funciona. Al correrlo se enciende el led permanentemente así como Rx flashea permanentemente este el verde o no. Presiono Esc sale el programa de python y se queda el led encendido y Rx flasheando. Si presiono el Reset de la placa Arduino se apaga LED y Rx, pero… Leer más »
Daniel
Humano

Oye amigo, quiero hacer el seguimiento de el color amarillo, ¿me podrias decir la escala HSV del amarillo?

Alain Vega Labrada
Humano
Me funciono solo una vez. Estoy usando python-2.7.10.amd64, pyserial-2.7.win32, opencv 3.0, numpy-1.9.3+mkl-cp27-none-win_amd64, Arduino Mega 2560 copia china con chipset CH341SER-64BIT, LifeCam HD-3000, windows 7 ultimate 64 bit Sp1 Spanish. El primer código que va al Arduino *.ino solo me llama la atención que nunca se cierra la comunicación del puerto serial quizás no haga falta. Cambie la linea “ser = serial.Serial(‘/dev/ttyUSB0’, 9600)” por “ser = serial.Serial(‘COM’, 9600)” y funcionó. Pero sucede que en vez de cerrar con Esc como esta previsto lo detuve con Ctrl+C luego de esto mas nunca funcionó. Del código en python me llama la atención que… Leer más »
Álvaro Pacheco
Humano
Buenos días! Primero de todo, felicitaros a los administradores de esta página y a ti Glare en especial por este tutorial. He tenido un problema con el código, me salía un error diciendo que el programa de python no era capaz de encontrar el puerto. Cambié esta línea de código: ser = serial.Serial(‘/dev/ttyUSB0’, 9600) por esta otra: ser = serial.Serial(“COM3”). COM3 es el puerto por el que suelen conectar las placas de arduino. Con este cambio el programa me funciona perfectamente, dejo el comentario por si alguien mas tiene este problema que he tenido yo. Un saludo a todos y… Leer más »
Hugo
Humano

como conecto la arduino con la rasberry

me podrías pasar un esquema

gonzalo
Humano

como descargo el arduino a las rasberry o donde pongo el codigo de arduino

Jess
Humano

Buenas tardes!

Disculpa estoy empezando este campo de detección de colores y mi duda es como se le hace para determinar los altos y los bajos del color de las matrices.

Joel
Humano

Glare estoy haciendo un programa que haga una discriminacion de tres colores con arduino y le puse lo siguiente y los reconoce segun su rango

verde_bajos = np.array([49,50,50], dtype=np.uint8)
verde_altos = np.array([80, 255, 255], dtype=np.uint8)
amarillo_bajos = np.array([15,50,50], dtype=np.uint8)
amarillo_altos = np.array([40,255,255], dtype=np.uint8)
rojo_bajos = np.array([140,50,50], dtype=np.uint8)
rojo_altos = np.array([243, 255, 255], dtype=np.uint8)

me puedes explicar como es funciona estas matrices que significa cada numero si no es mucho pedir gracias

falex
Humano

Hola buenas, soy algo nuevo en esto de OpenCV pero poseo conocimientos de electrónica. Quiero saber si es posible que nos contactemos y me puedas ayudar en un proyecto que estoy realizando. Te lo agradecería un montón y obviamente si necesitas ayuda en electrónica y electricidad también puedo brindarla 🙂

trackback

[…] Arduino y OpenCV con pySerial […]

wpDiscuz