Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Seguimiento automático de objetos por visión

Un servodispositivo de giro / inclinación que ayuda a un cámara para rastrear automáticamente objetos de color usando la visión.

Historia

Introducción

En mi último tutorial, exploramos cómo controlar un dispositivo Pan / Tilt Servo para colocar una PiCam. Ahora usaremos nuestro dispositivo para ayudar a la cámara a rastrear automáticamente los objetos de color

Esta es mi primera experiencia con OpenCV y debo confesar que estoy enamorado de esta fantástica “Biblioteca de visión por computadora de código abierto”.

OpenCV es gratuito para uso académico y comercial. Tiene interfaces C ++, C, Python y Java y es compatible con Windows, Linux, Mac OS, iOS y Android. En mi serie de tutoriales de OpenCV, nos centraremos en Raspberry Pi (es decir, Raspbian como sistema operativo) y Python. OpenCV fue diseñado para la eficiencia computacional y con un fuerte enfoque en aplicaciones en tiempo real. ¡Es perfecto para proyectos de computación física!

Paso 1:BOM - Lista de materiales

Partes principales:

(*) puedes comprar una plataforma Pan / Tilt completa con los servos o construir la tuya propia.

Paso 2:Instalar el paquete OpenCV 3

Estoy usando una Raspberry Pi V3 actualizada a la última versión de Raspbian (Stretch), así que la mejor manera de tener OpenCV instalado es seguir el excelente tutorial desarrollado por Adrian Rosebrock:Raspbian Stretch:Install OpenCV 3 + Python en su Raspberry Pi.

Probé varias guías diferentes para instalar OpenCV en mi Pi. El tutorial de Adrian es el mejor. Te aconsejo que hagas lo mismo, siguiendo sus pautas paso a paso.

Una vez que haya terminado el tutorial de Adrian, debería tener un entorno virtual OpenCV listo para ejecutar nuestros experimentos en su Pi.

Vayamos a nuestro entorno virtual y confirmemos que OpenCV 3 está instalado correctamente.

Adrian recomienda ejecutar el comando "fuente" cada vez que abra una nueva terminal para asegurarse de que las variables de su sistema se hayan configurado correctamente.

 fuente ~ / .profile 

Luego, entremos en nuestro entorno virtual:

 trabajar en cv 

Si ve el texto (cv) que precede a su mensaje, entonces está en el cv virtual entorno:

 (cv) pi @ raspberry:~ $ 

Adrian llama la atención que el entorno virtual cv Python es completamente independiente y está aislado de la versión predeterminada de Python incluida en la descarga de Raspbian Stretch. Por lo tanto, cualquier paquete de Python en el directorio global site-packages no estará disponible para el entorno virtual cv. De manera similar, cualquier paquete de Python instalado en paquetes de sitio de cv no estará disponible para la instalación global de Python.

Ahora, ingrese su intérprete de Python:

 python 

y confirme que está ejecutando la versión 3.5 (o superior)

Dentro del intérprete (aparecerá el “>>>”), importe la biblioteca OpenCV:

 importar cv2 

Si no aparecen mensajes de error, el OpenCV está instalado correctamente EN SU ENTORNO VIRTUAL PYTHON.

También puede verificar la versión de OpenCV instalada:

 cv2 .__ versión__ 

Debería aparecer la 3.3.0 (o una versión superior que se pueda lanzar en el futuro). La pantalla de impresión del terminal anterior muestra los pasos anteriores.

Paso 3:prueba tu cámara

Una vez que haya instalado OpenCV en su RPi, probemos si su cámara funciona correctamente.

Supongo que ya tiene una PiCam instalada en su Raspberry Pi.

Ingrese el siguiente código Python en su IDE:

 importar numpy como npimport cv2cap =cv2.VideoCapture (0) while (True):ret, frame =cap.read () frame =cv2.flip (frame, -1) # Voltear la cámara verticalmente gris =cv2.cvtColor (marco, cv2.COLOR_BGR2GRAY) cv2.imshow ('marco', marco) cv2.imshow ('gris', gris) si cv2.waitKey (1) &0xFF ==ord ('q'):breakcap.release () cv2.destroyAllWindows () 

El código anterior capturará la transmisión de video que será generada por su PiCam, mostrándola tanto en color BGR como en modo gris.

Tenga en cuenta que giré mi cámara verticalmente debido a la forma en que está ensamblada. Si no es su caso, comente o elimine la línea de comando "flip".

Alternativamente, puede descargar el código de mi GitHub:simpleCamTest.py

Para ejecutar, ingrese el comando:

 python simpleCamTest.py 

Para finalizar el programa, debes presionar la tecla [q] tor [Ctrl] + [C] en tu teclado

La imagen muestra el resultado.

Para saber más sobre OpenCV, puede seguir el tutorial:loading -video-python-opencv-tutorial

Paso 4:Detección de color en Python con OpenCV

Una cosa que intentaremos lograr será la detección y seguimiento de un determinado objeto de color. Para eso, debemos entender un poco más sobre cómo OpenCV interpreta los colores.

Henri Dang escribió un excelente tutorial sobre Detección de color en Python con OpenCV.

Por lo general, nuestra cámara funcionará con el modo de color RGB, que se puede entender pensando en todos los colores posibles que se pueden hacer a partir de tres luces de colores para rojo, verde y azul. Trabajaremos aquí con BGR (azul, verde, rojo) en su lugar.

Como se describió anteriormente, con BGR, un píxel está representado por 3 parámetros, azul, verde y rojo. Cada parámetro suele tener un valor de 0 a 255 (o de O a FF en hexadecimal). Por ejemplo, un píxel azul puro en la pantalla de su computadora tendría un valor B de 255, un valor G de 0 y un valor R de 0.

OpenCV funciona con el modelo de color HSV (Hue, Saturation, Value), que es una representación alternativa del modelo de color RGB, diseñado en la década de 1970 por investigadores de gráficos por computadora para alinearse más estrechamente con la forma humana la visión percibe los atributos de creación de color:

Genial. Entonces, si desea rastrear un determinado color usando OpenCV, debe definirlo usando el Modelo HSV.

Ejemplo

Digamos que debo rastrear un objeto amarillo como la caja de plástico que se muestra en la imagen de arriba. La parte fácil es encontrar sus elementos BGR. Puede usar cualquier programa de diseño para encontrarlo (usé PowerPoint).

En mi caso encontré:

  • Azul:71
  • Verde:234
  • Rojo:213

Luego, debemos convertir el modelo BGR (71, 234, 213) a un modelo HSV, que se definirá con límites de rango superior e inferior. Para eso, ejecutemos el siguiente código:

 importar sysimport numpy como npimport cv2blue =sys.argv [1] verde =sys.argv [2] rojo =sys.argv [3] color =np.uint8 ([[[azul, verde , rojo]]]) hsv_color =cv2.cvtColor (color, cv2.COLOR_BGR2HSV) hue =hsv_color [0] [0] [0] print ("El límite inferior es:"), print ("[" + str (hue- 10) + ", 100, 100] \ n") print ("El límite superior es:"), print ("[" + str (tono + 10) + ", 255, 255]") 

Alternativamente, puede descargar el código de mi GitHub:bgr_hsv_converter.py

Para ejecutar, ingrese el siguiente comando teniendo como parámetros los valores de BGR encontrados antes:

 python bgr_hsv_converter.py 71234213 

El programa imprimirá los límites superior e inferior del color de nuestro objeto.

En este caso:

 límite inferior:[24, 100, 100] 

y

 límite superior:[44, 255, 255] 

La Terminal PrintScreen muestra el resultado.

Por último, pero no menos importante, veamos cómo OpenCV puede "enmascarar" nuestro objeto una vez que hayamos determinado su color:

 import cv2import numpy as np # Leer la imagen - El 1 significa que queremos la imagen en BGRimg =cv2.imread ('yellow_object.JPG', 1) # redimensionar imag al 20% en cada axisimg =cv2.resize (img, (0,0), fx =0.2, fy =0.2) # convertir la imagen BGR a una imagen HSV range # El "dtype =np.uint8" significa que el tipo de datos es un entero de 8 bitslower_range =np.array ([24, 100, 100], dtype =np.uint8) upper_range =np.array ([44, 255, 255 ], dtype =np.uint8) # crea una máscara para imagemask =cv2.inRange (hsv, lower_range, upper_range) # muestra la máscara y la imagen una al lado de la otra cv2.imshow ('máscara', máscara) cv2.imshow ('imagen', img) # espere a que el usuario presione [ESC] mientras (1):k =cv2.waitKey (0) if (k ==27):breakcv2.destroyAllWindows () 

Alternativamente, puede descargar el código de mi GitHub:colorDetection.py

Para ejecutar, ingrese el siguiente comando que tiene en su directorio una foto con su objeto de destino (en mi caso:yellow_object.JPG):

 python colorDetection.py 

La imagen de arriba mostrará la imagen original ("imagen") y cómo aparecerá el objeto ("máscara") después de que se aplique la máscara.

Paso 5:seguimiento del movimiento de objetos

Ahora que sabemos cómo "seleccionar" nuestro objeto usando una máscara, sigamos su movimiento en tiempo real usando la cámara. Para eso, basé mi código en el tutorial Ball Tracking con OpenCV de Adrian Rosebrock.

Le sugiero que lea el tutorial de Adrian en detalle.

Primero, confirme si tiene la biblioteca imutils instalado. es la colección de funciones de conveniencia de OpenCV de Adrian para facilitar algunas tareas básicas (como cambiar el tamaño o voltear la pantalla). De lo contrario, ingrese con el siguiente comando para instalar la biblioteca en su entorno Virtual Python:

 pip instalar imutils 

Luego, descargue el código ball_tracking.py de mi GitHub y ejecútelo usando el comando:

 python ball_traking.py 

Básicamente, es el mismo código que el de Adrian, a menos que el "video vertical flip", que obtuve con la línea:

 frame =imutils.rotate (frame, angle =180) 

Además, tenga en cuenta que los límites de máscara utilizados fueron los que obtuvimos en el paso anterior.

Paso 6:probar los GPIO

Ahora que hemos jugado con los conceptos básicos de OpenCV, instalemos un LED en nuestro RPi y comencemos a interactuar con nuestros GPIO.

Siga el diagrama eléctrico anterior:el cátodo del LED se conectará a GPIO 21 y su ánodo a GND a través de una resistencia de 220 ohmios.

Probemos nuestro LED dentro de nuestro entorno virtual de Python.

¡Recuerde que es posible que RPi.GPIO no esté instalado en su entorno virtual Python! Para solucionar este problema, una vez que esté allí (recuerde confirmar que el (cv) está en su terminal), debe usar pip para instalarlo en su entorno virtual:

 instalación de pip RPi.GPIO 

Usemos la secuencia de comandos de Python para ejecutar una prueba simple:

 importar sysimport timeimport RPi.GPIO como GPIO # inicializar GPIO y variablesredLed =int (sys.argv [1]) freq =int (sys.argv [2]) GPIO.setmode (GPIO.BCM ) GPIO.setup (redLed, GPIO.OUT) GPIO.setwarnings (False) print ("\ n [INFO] LED parpadeante (5 veces) conectado a GPIO {0} cada {1} segundo (s)". Formato ( redLed, freq)) para i en el rango (5):GPIO.output (redLed, GPIO.LOW) time.sleep (freq) GPIO.output (redLed, GPIO.HIGH) time.sleep (freq) # hacer un poco de cleanupprint ("\ n [INFO] Saliendo del programa y limpieza \ n") GPIO.cleanup () 

Este código recibirá como argumentos un número GPIO y la frecuencia en segundos que nuestro LED debe parpadear. El LED parpadeará 5 veces y el programa finalizará. Tenga en cuenta que antes de terminar, liberaremos los GPIO.

Entonces, para ejecutar el script, debes ingresar como parámetros, LED GPIO y frecuencia .

Por ejemplo:

 python LED_simple_test.py 21 1 

El comando anterior parpadeará 5 veces el LED rojo conectado a “GPIO 21” cada “1” segundo.

El archivo GPIO_LED_test.py se puede descargar desde mi GitHub

La pantalla de impresión de Terminal anterior muestra el resultado (y, por supuesto, debe confirmar que el LED está parpadeando.

Ahora, trabajemos con OpenCV y algunas cosas básicas de GPIO.

Paso 7:Reconocimiento de colores e interacción GPIO

Comencemos a integrar nuestros códigos OpenCV con la interacción GPIO. Comenzaremos con el último código OpenCV e integraremos la biblioteca GPIO-RPI en él, por lo que encenderemos el LED rojo cada vez que la cámara encuentre nuestro objeto de color. El código utilizado en este paso se basó en el gran tutorial de Adrian, OpenCV, RPi.GPIO y GPIO Zero en Raspberry Pi:

Lo primero que debemos hacer es "crear" nuestro LED, conectándolo al GPIO específico:

 importar RPi.GPIO como GPIOredLed =21GPIO.setmode (GPIO.BCM) GPIO.setwarnings (False) GPIO.setup (redLed, GPIO.OUT) 

Segundo, debemos inicializar nuestro LED (apagado):

 GPIO.output (redLed, GPIO.LOW) ledOn =False 

Ahora, dentro del bucle, donde se crea el “círculo” cuando se encuentra el objeto, encenderemos el LED:

 GPIO.output (redLed, GPIO.HIGH) ledOn =True 

Descarguemos el código completo de mi GitHub:object_detection_LED.py

Ejecute el código usando el comando:

 python object_detection_LED.py 

Pruébelo con diferentes objetos (color y formato). Verá que una vez que el color coincide dentro de los límites de la máscara, el LED se enciende.

El siguiente video muestra algunas experiencias. Tenga en cuenta que solo se detectarán los objetos amarillos que permanezcan dentro del rango de color, encendiendo el LED. Los objetos con diferentes colores se ignoran.

Aquí solo usamos el LED como se explicó en el último paso. Ya tenía mi Pan Tilt ensamblado cuando hice el video, así que ignórelo. Lo manejaremos con el mecanismo PAN / TILT en el siguiente paso.

Paso 8:El mecanismo de giro e inclinación

Ahora que hemos jugado con los conceptos básicos de OpenCV y GPIO, instalemos nuestro mecanismo Pan / tilt.

Para obtener más información, visite mi tutorial:Pan-Tilt-Multi-Servo-Control

Los servos deben estar conectados a un suministro externo de 5V, teniendo su pin de datos (en mi caso, su cableado amarillo) conectado a Raspberry Pi GPIO como se muestra a continuación:

  • GPIO 17 ==> Servo de inclinación
  • GPIO 27 ==> Pan Servo

No olvide conectar los GND juntos ==> Raspberry Pi - Servos - Fuente de alimentación externa)

Puede tener como opción, una resistencia de 1K ohmios en serie, entre Raspberry Pi GPIO y pin de entrada de datos del servidor. Esto protegería su RPi en caso de un problema con el servo.

Aprovechemos también la oportunidad y pruebe nuestros servos dentro de nuestro entorno virtual de Python.

Usemos el script Python para ejecutar algunas pruebas con nuestros controladores:

 desde el tiempo import sleepimport RPi.GPIO como GPIOGPIO.setmode (GPIO.BCM) GPIO.setwarnings (False) def setServoAngle (servo, angle):pwm =GPIO.PWM (servo, 50) pwm .start (8) dutyCycle =angle / 18. + 3. pwm.ChangeDutyCycle (dutyCycle) sleep (0.3) pwm.stop () if __name__ =='__main__':import sys servo =int (sys.argv [1]) GPIO.setup (servo, GPIO.OUT) setServoAngle (servo, int (sys.argv [2])) GPIO.cleanup () 

El núcleo del código anterior es la función setServoAngle (servo, ángulo). Esta función recibe como argumentos, un número GPIO de servo y un valor de ángulo al que debe colocarse el servo. Una vez que la entrada de esta función es "ángulo", debemos convertirlo en un ciclo de trabajo equivalente.

Para ejecutar el script, debe ingresar como parámetros, servo GPIO y ángulo .

Por ejemplo:

 python angleServoCtrl.py 17 45 

El comando anterior colocará el servo conectado en GPIO 17 ("inclinación") con 45 grados en "elevación".

El archivo angleServoCtrl.py se puede descargar desde mi GitHub

Paso 9:encontrar la posición del objeto en tiempo real

La idea aquí será colocar el objeto en el medio de la pantalla usando el mecanismo Pan / Tilt. La mala noticia es que para empezar debemos saber dónde se encuentra el objeto en tiempo real. Pero la buena noticia es que es muy fácil, una vez que ya tenemos las coordenadas del centro del objeto.

Primero, tomemos el código "object_detect_LED" usado antes y modifiquémoslo para imprimir las coordenadas x, y del objeto fundado.

Descarga de mi GitHub el código:objectDetectCoord.py

El "núcleo" del código es la parte donde encontramos el objeto y dibujamos un círculo con un punto rojo en el centro.

 # solo proceda si el radio cumple con un tamaño mínimo si el radio> 10:# dibuje el círculo y el centroide en el marco, # luego actualice la lista de puntos rastreados cv2.circle (frame, (int ( x), int (y)), int (radio), (0, 255, 255), 2) cv2.circle (marco, centro, 5, (0, 0, 255), -1) # centro de impresión del círculo coordenadas mapObjectPosition (int (x), int (y)) # si el LED aún no está encendido, encienda el LED si no es ledOn:GPIO.output (redLed, GPIO.HIGH) ledOn =True 

Vamos a "exportar" las coordenadas centrales a mapObjectPosition (int (x), int (y)) función para imprimir sus coordenadas. Debajo de la función:

 def mapObjectPosition (x, y):print ("[INFO] Coordenadas del centro de objetos en X0 ={0} e Y0 ={1}". formato (x, y)) 

Al ejecutar el programa, veremos en nuestra terminal, las coordenadas de posición (x, y), como se muestra arriba. Mueva el objeto y observe las coordenadas. Nos daremos cuenta de que x va de 0 a 500 (de izquierda a derecha) e y va de o a 350 (de arriba a abajo). Vea las imágenes de arriba.

¡Genial! Ahora debemos usar esas coordenadas como punto de partida para nuestro sistema de seguimiento Pan / Tilt

Paso 10:Sistema de seguimiento de la posición del objeto

Queremos que nuestro objeto permanezca siempre centrado en la pantalla. Entonces, definamos, por ejemplo, que consideraremos nuestro objeto "centrado" si:

  • 220
  • 160

Fuera de esos límites, debemos mover nuestro mecanismo Pan / Tilt para compensar la desviación. Basado en eso, podemos construir la función mapServoPosition (x, y) como a continuación. Tenga en cuenta que las "x" y la "y" utilizadas como parámetros en esta función son las mismas que hemos utilizado antes para imprimir la posición central:

 # posicionar los servos para presentar el objeto en el centro del framedef mapServoPosition (x, y):global panAngle global tiltAngle if (x <220):panAngle + =10 if panAngle> 140:panAngle =140 positionServo (panServo, panAngle) if (x> 280):panAngle - =10 si panAngle <40:panAngle =40 positionServo (panServo, panAngle) if (y <160):tiltAngle + =10 si tiltAngle> 140:tiltAngle =140 positionServo (tiltServo, tiltAngle) if (y> 210):tiltAngle - =10 if tiltAngle <40:tiltAngle =40 positionServo (tiltServo, tiltAngle) 

Con base en las coordenadas (x, y), se generan los comandos de posición del servo, usando la función positionServo (servo, angle). Por ejemplo, supongamos que la posición y es "50", lo que significa que nuestro objeto está casi en la parte superior de la pantalla, lo que puede traducirse en que la "vista de la cámara" es "baja" (digamos un ángulo de inclinación de 120 grados). Por lo tanto, debemos "disminuir" el ángulo de inclinación (digamos a 100 grados), por lo que la vista de la cámara estará "arriba" y el objeto irá "hacia abajo" en la pantalla (y aumentará, digamos, 190).

El diagrama anterior muestra el ejemplo en términos de geometría.

Piense en cómo funcionará la cámara panorámica. tenga en cuenta que la pantalla no se refleja, lo que significa que si mueve el objeto a "su izquierda", se moverá en la pantalla para "su derecha", una vez que esté en oposición a la cámara.

La función positionServo (servo, ángulo) se puede escribir como:

 def positionServo (servo, ángulo):os.system ("python angleServoCtrl.py" + str (servo) + "" + str (angle)) print ("[INFO] Posicionamiento del servo en GPIO {0} a {1} grados \ n ".format (servo, ángulo)) 

Llamaremos al script mostrado antes para el posicionamiento del servo.

Tenga en cuenta que angleServoCtrl.py debe estar en el mismo directorio que objectDetectTrac.py

El código completo se puede descargar desde mi GitHub:objectDetectTrack.py

Paso 11:Conclusión

¡Como siempre, espero que este proyecto pueda ayudar a otros a encontrar su camino hacia el apasionante mundo de la electrónica!

Para obtener detalles y el código final, visite mi depósito de GitHub:OpenCV-Object-Face-Tracking

Para más proyectos, visite mi blog:MJRoBot.org

¡Saludos desde el sur del mundo!

¡Nos vemos en mi próximo tutorial!

Gracias,

Fuente: Seguimiento automático de objetos por visión


Proceso de manufactura

  1. Programación orientada a objetos de Python
  2. Seguimiento de Raspberry Pi Ball
  3. Speathe
  4. Reconocimiento facial en tiempo real:un proyecto de principio a fin
  5. Python - Orientado a Objetos
  6. Determinación de la precisión del seguimiento dinámico de objetos
  7. El filtro mejora la visión robótica en la estimación de pose 6D
  8. ¿Qué es una máquina de prensa automática?
  9. ¿Qué es una prensa automática?
  10. ¿Qué es una dobladora automática de tubos?
  11. ¿Qué es la mesa giratoria automática?