Informe Final Proyecto (7) (1)

UNIVERSIDAD CATOLICA DE SANTA MARIA PROGRAMA PROFESIONAL DE INGENIERIA ELECTRONICA PROCESAMIENTO DIGITAL DE SEÑALES MA

Views 62 Downloads 8 File size 2MB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

UNIVERSIDAD CATOLICA DE SANTA MARIA

PROGRAMA PROFESIONAL DE INGENIERIA ELECTRONICA

PROCESAMIENTO DIGITAL DE SEÑALES MARCO TEORICO

ROBOT SEGUIDOR DE OBJETOS BASADO EN EL RECONOCIMIENTO DE FORMAS Y COLORES

NEIRA MENDOZA JOSE RENE TAPIA CHIRE HUMBERTO ALONSO

AREQUIPA 2015

0

INTRODUCCIÓN

Las computadoras no "ven" las fotos ni los videos de la misma manera que las personas. Cuando una persona observa una foto, puede por ejemplo reconocer a su mejor amigo de pie delante de su casa . Desde la perspectiva de una computadora, esa misma imagen no es más que un montón de datos que se pueden interpretar como formas e información acerca de los valores del color. Si bien una computadora no reaccionará como las personas cuando ven esa foto, es posible entrenar a la computadora para que reconozca ciertos patrones de color y formas. Por ejemplo, se puede entrenar a una computadora para que reconozca los patrones comunes de formas y colores que componen la imagen digital de un rostro por ejemplo. Muchas de los objetos que tenemos en nuestro entorno son de forma geométrica y casi todos los objetos tienen un color característico que nos permite a simple vista diferenciarlos unos de otros , basados en esto es que se puede utilizar por ejemplo la forma de un objeto y su color para lograr que un robot lo siga , si bien es cierto q el robot no “ve” el objeto puede a través de un algoritmo identificarlo en el conjunto de datos que le llegan gracias a un sensor como por ejemplo una cámara de video. Para lograr que el robot identifique un objeto y lo siga se hacen uso de muchos algoritmos de procesamiento digital de imágenes. Las aplicaciones de esto en realidad están limitadas únicamente por la imaginación.

1

INDICE - Introducción

………………………………………………… pag. 1

- Indice

………………………………………………… pag. 2

- Primer Capítulo: Marco Teórico ……………………………… pag. 3 -

Reconocimiento De Patrones Para La Identificacion De Figuras Y Colores ………………………………………………… pag. 3 OPENCV………………………………………………… pag. 4 PYTHON………………………………………………… pag. 5 ARDUINO…………………………………………… … pag. 5

- Segundo Capítulo: Diagrama de Bloques del Sistema……….…pag. 7 - Tercer Capítulo: Diseño del Sistema……………………………pag. 8 -

PREPARACION DE LAS HERRAMIENTAS DE SOFTWARE NECESARIAS…………………………………………… pag. 8 PROCEDIMIENTO DE ELABORACIÓN DEL ALGORITMO pag 9 1. Capturar una imagen con una cámara. …………… pag. 10 2. Decidir que objeto y de que color se desea detectar pag 11 3. Convertir la imagen a un formato adecuado para su procesamiento. …………………………………..… pag. 12 4. Crear la máscara de un color………………….…… pag. 13 5. Eliminar ruido de la máscara………………….…… pag. 13 6. Aplicar un desenfoque Gaussiano…………….…… pag. 13 7. Aplicar un canny edge a la máscara…………..…… pag. 15 8. Detectar los contornos……………………………... pag. 17 9. Discriminar a los objetos por su tamaño………… pag. 17 10. Aproximar cada contorno………………………….. pag. 18 11. Encontrar el centro del objeto y obtener sus coordenadas pag 18 12. Mandar ordenes al robot………………………….… pag. 19

-

PROGRAMA DE CONTROL DEL ROBOT CON ARDUINO: pag 20

- Cuarto Capítulo: Pruebas……………………………………….… pag. 22 - Conclusiones……………………………………………………… pag. 25 - Bibliografía…………………………………………….………… pag. 26 - Anexos…………………………………………………….……… pag. 27

2

PRIMER CAPÍTULO: MARCO TEÓRICO RECONOCIMIENTO DE PATRONES PARA LA IDENTIFICACION DE FIGURAS Y COLORES

El reconocimiento de patrones es la ciencia que se ocupa de los procesos sobre ingeniería, computación y matemáticas relacionados con objetos físicos o abstractos, con el propósito de extraer información que permita establecer propiedades de entre conjuntos de dichos objetos. El reconocimiento

de

patrones ,también

llamado lectura

de

patrones, identificación de figuras y reconocimiento de forma, consiste en el reconocimiento de patrones de señales. Los patrones se obtienen a partir de los procesos de segmentación, extracción de características y descripción dónde cada objeto queda representado por una colección de descriptores. El sistema de reconocimiento debe asignar a cada objeto su categoría o clase (conjunto de entidades que comparten alguna característica que las diferencia del resto). Para poder reconocer los patrones se siguen los siguientes procesos: 1. Adquisición de datos 2. Extracción de características 3. Toma de decisiones El punto esencial del reconocimiento de patrones es la clasificación: se quiere clasificar una señal dependiendo de sus características. Señales, características y clases pueden ser de cualquiera forma, por ejemplo se puede clasificar imágenes digitales de letras en las clases «A» a «Z» dependiendo de sus píxeles o se puede clasificar ruidos de cantos de los pájaros en clases de órdenes aviares dependiendo de las frecuencias. Nosotros clasificaremos objetos en base a su color y forma geométrica.

Imagen nro 1 “Reconocimiento de patrones”

3

OPENCV OpenCV (Open Source Computer Vision Library) es una librería de software de código abierto que incluye cientos de algoritmos de visión por computadora y de machinelearning. OpenCV fue construido para proporcionar una infraestructura común para aplicaciones de visión por computador y para acelerar el uso de la percepción de la maquina en los productos comerciales. Una de sus principales virtudes es ser de código abierto lo que permite a cualquiera utilizar y modificar su código. La biblioteca cuenta con más de 2.500 algoritmos optimizados , que incluye un amplio conjunto de clásico y algoritmos de visión por computador y aprendizaje automático con tecnología de última generación. Estos algoritmos se pueden utilizar para detectar y reconocer rostros , identificar objetos , clasificar las acciones humanas en videos, movimientos de cámara , objetos en movimiento, extraer modelos 3D de objetos , producir nubes de puntos 3D de cámaras estéreo , unir imágenes para producir una alta resolución de imagen de toda una escena , encontrar imágenes similares de una base de datos de imágenes, eliminar los ojos rojos de las imágenes tomadas con flash, seguir los movimientos de los ojos , reconocer el paisaje y establecer marcadores para cubrirás de realidad aumentada , etc. OpenCV tiene más de 47 mil personas de usuario la comunidad y la estimación del número de descargas que superen 7.000.000 . La biblioteca se utiliza ampliamente en las empresas , grupos de investigación y por los organismos gubernamentales . Cuenta con interfaces de C ++ , C, Python , Java y MATLAB y es compatible con Windows , Linux , Android y Mac OS . OpenCV se inclina principalmente hacia las aplicaciones de visión en tiempo real y se aprovecha de instrucciones MMX y SSE cuando están disponibles . Se están desarrollando de forma activa en este momento interfaces con todas las funciones CUDA y OpenCL. OpenCV está escrita de forma nativa en C ++ y tiene una interfaz de plantilla que funciona a la perfección con contenedores STL

4

PYTHON Python es un lenguaje de programación orientado a objetos, interpretado, e interactivo . A menudo se compara con Lisp, Tcl , Perl , Ruby , C # , Visual Basic, Visual Fox Pro , Scheme o Java .

Python combina notablemente la potencia con una sintaxis muy clara. Cuenta con módulos , clases , excepciones , tipos de datos dinámicos de muy alto nivel , y tipado dinámico . Hay interfaces a muchas llamadas y bibliotecas del sistema , así como a varios sistemas de ventanas . Nuevos módulos incorporados son fácilmente escritos en C o C ++ (u otros idiomas , dependiendo de la aplicación elegida) . Python también se puede utilizar como un lenguaje de extensión para aplicaciones escritas en otros idiomas que necesitan de scripting o de automatización de interfaces fáciles de usar . Python es un lenguaje de programación interpretado cuya filosofía hace hincapié en una sintaxis que favorezca un código legible. Se trata de un lenguaje de programación multiparadigma, ya que soporta orientación a objetos, programación imperativa y, en menor medida, programación funcional. Es un lenguaje interpretado, usa tipado dinámico y es multiplataforma. Es administrado por la Python Software Foundation. Posee una licencia de código abierto, denominada Python Software Foundation License,1 que es compatible con la Licencia pública general de GNU a partir de la versión 2.1.1, e incompatible en ciertas versiones anteriores.

ARDUINO Arduino es una plataforma de hardware libre, basada en una placa con un microcontrolador y un entorno de desarrollo, diseñada para facilitar el uso de la electrónica en proyectos multidisciplinares. El hardware consiste en una placa con un microcontrolador Atmel AVR y puertos de entrada/salida.4 Los microcontroladores más usados son el Atmega168, Atmega328, Atmega1280, y Atmega8 por su sencillez y bajo coste que permiten el desarrollo de múltiples diseños. Por otro lado el software consiste en un entorno

5

de desarrollo que implementa el lenguaje de programación Processing/Wiring y el cargador de arranque que es ejecutado en la placa. Arduino se puede utilizar para desarrollar objetos interactivos autónomos o puede ser conectado a software tal como Adobe Flash, Processing, Max/MSP, Pure Data. Las placas se pueden montar a mano o adquirirse. El entorno de desarrollo integrado libre se puede descargar gratuitamente. Arduino puede tomar información del entorno a través de sus entradas analógicas y digitales, puede controlar luces, motores y otros actuadores. El microcontrolador en la placa Arduino se programa mediante el lenguaje de programación Arduino (basado en Wiring) y el entorno de desarrollo Arduino (basado en Processing). Los proyectos hechos con Arduino pueden ejecutarse sin necesidad de conectar a un ordenador. También cuenta con su propio software que se puede descargar de su página oficial que ya incluye los drivers de todas las tarjetas disponibles lo que hace más fácil la carga de códigos desde el computador.

6

SEGUNDO CAPÍTULO: DIAGRAMA DE BLOQUES DEL SISTEMA

CONVERSION A FORMATO HSV

MASCARA DE COLOR

ELIMINACION DE RUIDO Y DESENFOQUE GAUSSIANO

OBTENCION DE LAS COORDENADAS DEL CENTRO DEL OBJETO DETECTADO

APROXIMACION DE CONTORNO E IDENTIFICACION DE OBJETO

DETECCION DE CONTORNOS CON FILTRO CANNY EDGE

OBTENCION DE LA IMAGEN

ENVIAR ORDENES A ROBOT BASADAS EN LAS COORDENADAS

ACTIVACION DE MOTORES DE ACUERDO A LAS ORDENES

Diagrama de bloques Numero 1 “Obtención ,detección de objetos y control de robot”

7

TERCER CAPÍTULO: DISEÑO DEL SISTEMA En el diseño del sistema se tomaron en cuenta diversos aspectos para elegir las herramientas adecuadas para lograr los objetivos del proyecto. Uno de ellos era utilizar software y hardware de código abierto, para ahorrar los costes y proporcionar una idea replicable cuyas ventajas resultan más que obvia al utilizar software libre. Por lo que decidimos utilizar Python como lenguaje de programación para el algoritmo en lugar de C y Matlab , y además porque OpenCV la librería que utilizaríamos tiene algoritmos tanto para Python como para C por lo que combinan a la perfección.

Otro aspecto fue la idea de ahorrar tiempo y concentrarse en lo más importante: que era lograr el reconocimiento de los objetos y no invertir mucho tiempo en el control del robot ya que nuestro trabajo principal era elaborar el algoritmo de reconocimiento de patrones para la identificación de objetos ,asi que se decidió utilizar una gran herramienta cuya popularidad está bien justificada debido a su facilidad de desarrollo: Arduino, haciendo uso de Arduino y su placa de desarrollo se pudo reducir considerablemente el tiempo de diseño del robot .y su programación.

PREPARACION DE LAS HERRAMIENTAS DE SOFTWARE NECESARIAS

Se utilizo Python 2.7.4 OpenCV 2.4.10 Arduino IDE 1.6.4 Windows 8 de 32bits Luego de instalar los paquetes necesario para programar y ejecutar código escrito en Python se procedió a Instalar la librería OpenCV asi como otros librerías de Python; como Numpy que es una librería para computación científica de Python y que nos serviría para poder usar vectores y operaciones matemáticas complejas , y la librería Pyserial que nos permitiría hacer la comunicación entre nuestra PC y la placa Arduino a través del puerto USB. Además se instaló el IDE de Arduino para la programación del robot.

8

PROCEDIMIENTO DE ELABORACIÓN DEL ALGORITMO Pasos necesarios para el reconocimiento ,detección de figuras y control del robot: 1. Capturar una imagen con una cámara. 2. Decidir que objeto y de que color se desea detectar 3. Convertir la imagen a un formato adecuado para su procesamiento. 4. Crear la máscara de un color 5. Eliminar ruido de la máscara 6. Aplicar un desenfoque Gaussiano 7. Aplicar un canny edge a la máscara 8. Detectar los contornos 9. Discriminar a los objetos por su tamaño 10. Aproximar cada contorno 11. Encontrar el centro del objeto y obtener sus coordenadas 12. Mandar ordenes al robot

9

PROCESO DE DISEÑO 1. CAPTURAR IMAGENES CON UNA CÁMARA.

Como es de suponer necesitamos una cámara de video para obtener imágenes del entorno para poder procesarlas .Para esta tarea elegimos una cámara de resolución media de marca Micronics modelo w304 la cual satisface nuestras necesidades. Esta cámara se conecta vía USB a nuestro computador lo cual facilita la obtención de video a una buena calidad .

Imagen nro 2 “Cámara Web Micronics”

Inicio del algoritmo:

import serial import time import cv2 import numpy as np ser=serial.Serial('COM3',9600,timeout=0) captura=cv2.VideoCapture(1)

Con esta parte del algoritmo tenemos llamadas las librerías que utilizaremos y se inició la captura de frames de la cámara de video; el numero 1 indica al programa que debe utilizar la cámara externa y no la cámara de la laptop. Además se inicia el puerto serial COM3 que es donde se conecta nuestro Arduino a 9600 baudios.

10

2. DECIDIR QUE OBJETO Y DE QUE COLOR SE DESEA DETECTAR

Por medio de una consola se pide al usuario que le diga al robot que figura debe seguir y de qué color de esta manera el robot sabrá que objeto buscar. En base a estos dos datos se creó una pequeña tabla con los valores respectivos de los colores y del número de vértices de los objetos, en este caso usaremos los 3 colores básicos (rojo,azul y verde)y dos tipos de figuras cuadrados y triángulos.

print "INICIO DE PROGRAMA" print "PRESIONA ESCAPE PARA TERMINAR" print "QUE FIGURA QUIERES SEGUIR??" tipofigura = raw_input() print "DE QUE COLOR ES LA FIGURA" colorfigura = raw_input()

if tipofigura == 'triangulo': numerodevertices = 3

if tipofigura == 'cuadrado': numerodevertices = 4

if colorfigura == 'azul': #colores hsv(azules) bajos=np.array([67,40,105],dtype=np.uint8) altos=np.array([129,255,182],dtype=np.uint8)

if colorfigura == 'verde': #colores hsv(verdes) bajos = np.array([49,50,50],dtype=np.uint8) altos = np.array([80, 255, 255],dtype=np.uint8)

if colorfigura == 'rojo': #colores hsv(verdes) bajos = np.array([0,20,20], dtype=np.uint8) 11

altos = np.array([20,255,255], dtype=np.uint8)

Estos valores son cargados en unas variables dependiendo de la eleccion las cuales serán utilizadas por el algoritmo luego para detectar los colores y las formas.

3. CONVERTIR

LA

IMAGEN

A

UN

FORMATO

ADECUADO

PARA

SU

PROCESAMIENTO.

Debido a que la detección del objeto está basado primero que nada en su color se utilizó el formato HSV en lugar del RGB ya que es más fácil analizar las imágenes y sus colores de esta manera. El modelo HSV (del inglés Hue, Saturation, Value – Matiz, Saturación, Valor), también llamado HSB (Hue, Saturation, Brightness – Matiz, Saturación, Brillo), define un modelo de color en términos de sus componentes. El modelo HSV fue creado en 1978 por Alvy Ray Smith. Se trata de una transformación no lineal del espacio de color RGB, y se puede usar en progresiones de color. Se inicia un bucle infinito de tipo while para que cada frame de la cámara sea analizado y procesado de manera de poder identificar los colores y las formas.

while (1): #captura imagen _,imagen=captura.read() #convertir a hsv hsv=cv2.cvtColor(imagen,cv2.COLOR_BGR2HSV)

Cada imagen se guarda en una variable llamada “imagen” y se procesa y convierte a hsv en cada ciclo del bucle while.

12

4. CREAR LA MÁSCARA DE UN COLOR

Basados en la elección del color en el paso 1 se aplica una máscara a la imagen de manera que solo aquellos pixeles que estén en el rango de color que queremos sean utilizados . Estos pixeles se muestran de un color y todos lo demás pixeles de color negro asi, primeramente se logra seleccionar únicamente aquellos objetos que cumplan con nuestra restricción de color. El rango de colores esta dado por los valores bajos y altos del color elegido en RGB, por ejemplo para color azul el valor bajo sería un celeste y el alto un azul metálico.

#mascara para detectar un color mask=cv2.inRange(hsv,bajos,altos)

5. ELIMINAR RUIDO DE LA MÁSCARA:

Para que la detección sea mas efectiva se eliminaran aquellos grupos de pixeles pequeños ya que se supone que si son muy pequeños no son objetos que deseemos seguir .Para lograr esto se usa un filtro de OpenCV.

#filtro de pixeles pequeños kernel=np.ones((6,6),np.uint8) mask=cv2.morphologyEx(mask,cv2.MORPH_CLOSE,kernel) mask=cv2.morphologyEx(mask,cv2.MORPH_OPEN,kernel)

Con esto solo veremos los objetos grandes.

6. APLICAR UN DESENFOQUE GAUSSIANO

Para facilitar la detección de los contornos y de esta manera facilitar el trabajo al filtro Canny Edge se realiza un filtro Gaussiano que permite suavizar los contornos del objeto detectado.

13

El desenfoque gaussiano es un efecto de suavizado para mapas de bits generado por software de edición gráfica. El efecto es generado por medio de algoritmos matemáticos. En esencia, el efecto mezcla ligeramente los colores de los píxeles que estén vecinos el uno al otro en un mapa de bits (imagen), lo que provoca que la imagen pierda algunos detalles minúsculos y, de esta forma, hace que la imagen se vea más suave (aunque menos nítida o clara) respecto a que los bordes presentes en la imagen se ven afectados.

Imagennro 3 “Filtro Gaussiano a diferentes o”

Puede ser representado en 2D como :

Donde

es el valor máximo y

representa la varianza (para cada variable

y )

#Desenfoque Gaussiano blur=cv2.GaussianBlur(mask,(5,5),0) Información sacada de la documentación de OPENCV: http://docs.opencv.org/doc/tutorials/imgproc/gausian_med ian_blur_bilateral_filter/gausian_median_blur_bilateral_ filter.html?highlight=gaussian

14

7. APLICAR UN CANNY EDGE A LA MÁSCARA:

El detector de Canny Edge fue desarrollado por John F. Canny en 1986. También conocido por muchos como el detector óptimo , el algoritmo de Canny pretende satisfacer tres criterios principales : Baja tasa de error : Significa una buena detección de solo bordes existentes . Buena localización : La distancia entre los píxeles del borde detectado y borde verdadero es mínima. Respuesta mínima : Sólo una respuesta del detector al borde.

PASOS: Filtrar cualquier ruido. El filtro de Gauss se usa para este propósito. Un ejemplo de un kernel gaussiana de tamaño = 5 que podría ser utilizado se muestra a continuación:

Encontrar el gradiente de intensidad de la imagen. Para ello, seguimos un procedimiento análogo al de Sobel:

Aplique un par de máscaras de convolución (en direcciones x e y):

15

Encontrar la fuerza del gradiente y la dirección con:

La dirección se redondea a uno de los cuatro ángulos posibles (es decir, 0, 45, 90 o 135) Se aplica no supresión máxima. Esto elimina los píxeles que no se consideran parte de un borde. Por lo tanto, sólo las líneas finas (bordes candidatos) se mantendrán. Histéresis: El paso final. Canny hace uso de dos umbrales (superior e inferior): Si un gradiente de pixel es mayor que el umbral superior, el píxel se acepta como un borde. Si un valor de gradiente píxel está por debajo del umbral inferior, entonces se rechaza. Si el gradiente de píxel es entre los dos umbrales, entonces será aceptada sólo si está conectado a un píxel que está por encima del umbral superior. Canny recomendó un superior: relación más baja entre 2: 1 y 3: 1.

#Difuminado Canny edge edges=cv2.Canny(mask,1,2)

Imagen nro 4 “Imagen con un filtro Canny Edge aplicado” Información sacada de la documentación de OPENCV: http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/ca nny_detector/canny_detector.html?highlight=canny

16

8. DETECTAR LOS DIFERENTES CONTORNOS:

#Deteccion de contornos contours,hier=cv2.findContours(edges,cv2.RETR_TREE,cv2.CHAIN_APP ROX_SIMPLE) areas=[cv2.contourArea(c) for c in contours]

Contours es una lista que contiene otras listas, cada una de las cuales contiene todas las coordenadas de los puntos de cada contorno Hier guarda la jerarquía de los contornos. La jerarquía ayuda a establecer qué contornos pertenecen a un mismo objeto, cuáles son más importantes, etc. cv2.findContours recibe 3 parámetros. El primero es la máscara dónde hay que buscar los contornos. El segundo es el método para establecer la jerarquía. El tercer parámetro es el algoritmo utilizado para reducir el número de puntos del contorno. En la segunda línea calculamos el área con un bucle que va iterando entre las listas de puntos de contours y guarda su área en una lista.

Imagen nro 5 “Deteccion de contornos”

9. DISCRIMINAR A LOS OBJETOS POR SU TAMAÑO

Solo aquellos objetos de mas de 500 pixeles deben ser tomados en cuenta

#buscamos solo figuras grandes i=0 17

for extension in áreas if extension >500: actual=contours[i]

10. APROXIMAR CADA CONTORNO

approx=cv2.approxPolyDP(actual,0.05*cv2.arcLength(a ctual,True),True) if len(approx)== numerodevertices : cv2.drawContours(imagen,[actual],0,(0,0,255),2)

Ahora llega la parte de determinar si el objeto del color que ha detectado tiene también la forma que queremos para lo cual se calcula el número de vértices por medio de una aproximación y si coincide con el número de vértices de la forma que elegimos le dibuja un contorno . En este momento ya se logró detectar el objeto que deseábamos seguir.

11. ENCONTRAR EL CENTRO DEL OBJETO Y OBTENER SUS COORDENADAS

Y como el objetivo desde el principio fue seguirlo , se hace uso de la función “moments” la cual entre otras cosas nos da el área del objeto y las coordenadas de su centro , lo cual nos permitirá utilizar un eje de coordenadas para indicarle al robot en que lugar respecto a su cámara se encuentra el objeto que desea seguir

moments=cv2.moments(mask) area = moments['m00'] x = int(moments['m10']/moments['m00']) y = int(moments['m01']/moments['m00']) cv2.rectangle(imagen,(x,y),(x+2,y+2),(0,0,255),2)

18

Imagen nro 6 “Objeto detectado y centro marcado”

12. MANDAR ORDENES AL ROBOT

Como ya tenemos las coordenadas del centro del objeto ya podemos ordenarle a nuestro robot hacia dónde dirigirse. Estas órdenes se las damos a través del puerto serial. Se dividió al plano de visión del robot en 3 partes de aproximadamente el mismo tamaño , en este caso de 200 pixeles cada uno para hacer los 600 pixeles de ancho que tiene la imagen. Dependiendo de la ubicación del centro del objeto ,con respecto a las 3 divisiones se mandan las ordenes derecha, izquierda o de frente.

if (area>1000000): if (x>400): print"derecha x=",x,"y=",y ser.write("i") elif (0