Introducción:
Esta última práctica, es más extensa que las demás ya que
integra distintos elementos, consiste en leer un código QR, un texto o frase y
hacer un contador de bolígrafos (o similar), que cuenta hacia adelante si se
pasan en una dirección y hacia atrás si se pasan en la contraria. Antes de todo
esto se debe hacer un programa de reconocimiento facial, sin el cual no se
permitirá continuar con el programa, todo ello se hará mediante una cámara
montada sobre un motor paso a paso, excepto el programa de reconocimiento
facial que se hará con la propia cámara del PC. El programa también deberá
incluir tres botones uno para cada posición a la que deseemos ir: QR, texto o
contador. También se incluirá una cuarta posición como punto inicial.
Desarrollo:
Lo primero que hice fue fabricar un soporte para integrar el
montaje de la práctica, con un tablón de madera de unos 450x450 mm, le perfore
un agujero en el medio para introducir el motor paso a paso y le añadí unos
tacos para levantarlo de la superficie, de tal manera que la cámara montada
sobre el motor quedara a la altura deseada. A esa base de madera le añadi 4
paredes, una en cada lado del cuadrado de la base. En las paredes pondré cada
una de las fases que ha de reconocer la cámara, el texto, el código QR y el contador,
para este último le puse dos tiras de cinta aislante en cada extremo, que
serían los limites por donde debiera pasar el objeto a contar.
Tras realizar el montaje, empiezo con la parte de Vision
Builder, realice varios estados, uno para cada parte de reconocimiento de las
fases, otro para el reconocimiento facial y estados intermedios para valorar
las elecciones a tomar en función de los resultados obtenidos (Ver Imagen
inferior).
Como se puede observar hay estados que tiene varias
transiciones, esto es debido a que en función de lo que haya ocurrido en un
estado puedo querer ir hacia un estado o hacia otro.
Ahora explicare detalladamente cada estado, así como las
transiciones que lo acompañan.
IDENTIFICACIÓN: En este
estado adquirí la imagen de la cámara del PC, le quitare un plano de color para
dejar la imagen en escala de grises, y de este modo utilizar dos “Match
Paterns” para detectar singularidades únicas de mi rostro facial como pueden
ser el tono de mi piel o de mis ojos, con estos primeros dos match patterns me
aseguro de que detecte siempre rostros faciales, sin embargo en escala de
grises cualquier rostro puede tener semejante tono al mío, por lo que hace
falta otra condición mas que será “Geometry Setup”, con este paso mido la
distancia entre mis ojos y la distancia entre un ojo y mi boca ya que esas
distancias si que van a ser exclusivamente mías, y con esto ya me aseguro de
que solo me detecte a mi. Acabo el estado poniendo un “Set Inspection Status”,
para no permitir cambiar de estado hasta que se cumplan los pasos
anteriores. Tiene dos transacciones la
transición “default”, volverá siempre al mismo estado, pero la transición
“Recon Correcto”, se activara cuando el paso “Set Inspection Status” este en
Pass, por lo que se pasara al siguiente estado.
El primer bloque es adquirir imagen de la cámara del
ordenador, tendremos que darle una nueva calibración:
Selecionamos
la camara del ordenador y segidamente pinchamos en la pestaña de calibracion,
aparecera la siguiente ventana, en la que selecionaremos “Create Calibration”
La primera venta de la nueva calibración nos pedirá el
nombre y el operador de la nueva calibración. Después pulsamos “Next”.
La siguiente ventana, es para seleccionar el tipo de calibración,
seleccionaré el primero que sirve para convertir las coordenadas en pixeles a coordenadas
en un sistema real de medida, basándonos en una distancia conocida
Pulsando Next, tendremos otra ventana de configuración en la
que seleccionaremos la fuente de la imagen que queremos calibrar.
En la siguiente ventana, tendremos que especificar dos
puntos en la imagen y decirle a cuanta medida equivale en el mundo real.
Nos saltamos el siguiente paso, que es para distorsionar la
imagen en caso de lentes especiales de cámaras, y pasamos al paso 6 que sirve
para darle a la calibración un eje de coordenadas.
Y el último paso, el paso 7 es un resumen de toda la
configuración que hemos hecho previamente, para finalizar la calibración pulsamos
“OK”.
El siguiente bloque es para quitar un plano de color, seleccionamos
“Edit” y en el desplegable seleccionamos “Full Image” ya que queremos hacerlo
para toda la imagen.
Al pulsar “Edit” nos aparecerá otra nueva ventana en la que seleccionaremos
el bloque de color, y en ese bloque la opción extraer plano de color.
Y extraemos el plano de color que queramos, yo extraje el
rojo porque con la imagen que capte en ese momento era la mejor opción.
El siguiente bloque es un “Match Patern”, con el que
detectare uno de mis ojos, al selconarlo y poner en egion de interés “Constant”,
podemos dibujar un cuadro con el puntero donde queramos hacer nuestro “Pattern”.
En la segunda pestaña en Template, podemos editar el cuadro
que hemos dibujado con “Edit Template”, por si queremos omitir partes de la
imagen que hemos seleccionado.
En la siguiente pestaña “Settings”, le especificamos el número
de “Matches” que debe detectar y el porcentaje de semejanza que debe tener para
ser valido.
El siguiente boque a explicar es “Geometry” y sirve para
definir una distancia entre dos puntos en una imagen, por ejemplo la distancia
entre ojo y ojo, se le dan dos puntos con el puntero en la imagen y se le dice la
distancia a la que corresponde.
El último paso es el “Set Inspection Status” que sirve para
no finalizar el estado hasta que se cumplan todos los pasos anteriores, aunque
se le pueden poner otros modos de funcionamiento.
DATOS: Este es el estado
inicial, el punto muerto de la cámara donde no se debe detectar nada, aquí
adquiero la imagen de la cámara montada sobre el motor PaP. Le colocare tres
“Geometric Matching” cada uno correspondiente a una de las fases que han de
detectarse, es decir el QR, el texto, y el contador. Utilizo este tipo de paso
ya que para detectar más fácilmente las fases dibuje una figura geométrica en
cada una de ellas, un cuadrado, un triángulo y un circulo, por eso la condición
para estar en este estado es que no se reconozca ninguno, y por lo tanto querrá
decir que acabo de iniciar el programa o que acabo de mover el motor para
cambiar de fase, por eso también redefino la variable Global que creare para el
contador a “0”. Este estado cuenta con 4 transiciones, la transición “default”
vuelve al mismo estado, y las otra tres corresponden a cada uno de los
“Geometric Matching” que coloque, en el momento que detecte uno de ellos se
pasara al estado correspondiente, es decir si se activa el “Geometric Matching”
del contador, querrá decir que e motor ha girado a la posición del contador y
se pasara al estado del contador, y así con los demás.
El bloque nuevo que aparece aquí
es “Geometric Matching”, sirve para detectar formas geométricas bien definidas.
Se puede editar el “Template” de
igual manera que en el “Match Pattern” como vimos anteriormente, y las demás
opciones son similares al “Match Pattern”.
El siguiente bloque es “Set
Variable 1” que es para administrar una variable que tengamos, en mi caso aquí le
digo que se reinicialice a su valor inicial.
QR: En este estado,
adquirimos la imagen de la cámara otra vez, quitamos plano de color y leemos el
código QR, por ultimo ponemos el “Geometric Matching” del QR para que se cumpla
el paso y este continuamente leyendo el código QR ya que la transición “default”
actúa sobre el mismo estado, la otra transición que tiene es “Salir QR” que se
activara en el momento en que no se detecte
el “Geometric Matching” del QR y nos llevara al estado Realimentación.
El bloque que explicare será el “Read 2D Barcode 1” ya que los demás ya
han sido explicados, este bloque leerá un código QR, si previamente lo ha
detectado.
Letras: Este es el estado para leer el texto, adquiero imagen otra vez, quito el plano de color y leo el texto con el paso “Read/Verify Text”, a la hora de usar este paso hay calibrar la imagen para que detecte solo las letras y los signos, una vez ya solo te aparecen las letras y los signos en cuadrados rojos, le dices a que letra o símbolo corresponde cada uno, ya que siempre serán los mismos, si se cambiaran el texto con nuevas letras o signos esto no funcionaria. Una vez leído el texto se añade el “Geometric Matching” del texto y de igual manera que con las transiciones del QR mientras detecte el “Geometric Matching” del texto, la transición “default” volverá al mismo estado, pero en el momento que se pierda, la transición “Salir Letras” cambiara al estado de Realimentación. El último paso es para mostrar el texto leído en la pantalla.
El bloque texto leído, es para
leer caraceteres ,se debe seleccionar la zona donde se encuentrar los
caracteres mediante un recuadro con el puntero, seguidamente en la pestaña “mode”
hay una opción que pude que detecte los caracteres automáticamente.
Si no es así, le daremos a la opción
“Edit Character Set File” y nos aparecerá una nueva ventana en la que podemos seleccionar
cada carácter individualmente y definirle el valor que tiene.
CONTADOR: En este paso se adquiere imagen otra vez, y se ponen dos “Find Straight Edge” uno para la derecha y otro para la izquierda, en cada una de las tiras de cinta aislante que habíamos colocado previamente, de este modo en cuanto se pase el objeto por encima de alguna (el objeto debe ser de un tono claro) se activara dicho paso. Por último se mostrara por pantalla el valor de la variable global contador. También le pondré el “Geometric Matching” correspondiente al contador, mientras este activado la transición “default” volverá al mismo estado, pero si se desactiva el programa pasara al estado Realimentación. Este estado tiene dos transiciones más, una para cada borde, si se detecta el borde derecho, el programa pasara al estado ContRest y si se detecta el borde izquierdo el programa para al estado ContSum.
El bloque “BoliIzqrd”, sirve para
detectar bordes verticales, se dibuja con el puntero el cuadro donde se quiera
encontrar bordes, y se selecciona en la pestaña ”Settings”, la dirección por
donde se quiere detectar el borde, si se quiere detectar de caro a oscuro o
viceversa y si se quiere coger el primer borde detectado o el mejor borde
detectado.
CONTSUM: En este estado se vuelve a adquirir imagen, se le quita el plano de color y se añade el “Geometric Matching” para que en el momento que no se detecte se vaya al estado Realimentación, seguidamente añadimos una copia de la detección del borde derecho, de este modo sabré que el boli primero ha pasado por el borde izquierdo (ya que sino no se habría entrado en este estado) y luego ha pasado por el borde derecho por lo que el contador se incrementara en una unidad, que lo haremos en el siguiente estado. Por lo tanto habrá 3 transiciones en este estado, “default” que ira al mismo estado, “Salir sumador” que ira al estado Realimentacion y la transición “Detbolidrch1” que se activara cuando e detecte borde derecho y nos llevara al estado siguiente que es Sumador.
SUMADOR: Este estado
sirve para sumar una unidad a la variable contador, ya que si se ha entrado en
este estado quiere decir que el boli primero ha pasado por el borde izquierdo y
luego por el derecho. Le he añadido un delay de 1 sg para no cuente varias
veces. Solo tiene una transición la de por defecto “default” que llevara el
programa al estado Contador de nuevo.
REALIMENTACIÓN: Este es
tan solo un estado de transición, ya que solo posee un delay de 1 sg y una
transición “default” que devuelve el programa al estado Datos. Es necesario
para recibir todas las transiciones de salida de los demás estados, y
renviarlas al estado Datos.
Los estados Contrest y restador
son totalmente idénticos a sus análogos de la parte de la suma, con la salvedad
de que se resta la variable en una unidad ya que el boli se desplaza de derecha
a izquierda.
Con esto quedaría terminada la
parte de Vision Builder, seguidamente se compilaría y se obtiene un proyecto en
LabView. Para hacerlo todo en el mismo proyecto, integre el programa para mover
el PaP en el programa compilado que obtenía de Vision Builder.
El motor PaP se controlara con
una controladora y esta a su vez con una placa Arduino, es necesario
suministrar al motor (a la controladora una fuente externa de tensión de 12
voltios). El panel frontal de nuestro programa contara con tres botones, cada
uno de ellos girara el motor a la posición que indique, y si ninguno esta
pulsado el motor se desplazara a la posición inicial, de esta forma se sabrá en
todo momento donde se encentra el motor, los botones están hechos de tal forma
que si pulsas uno desaparecen los demás, de este modo, se debe despulsar el
botón para que aparezcan de nuevo y al hacerlo el motor se desplaza a la
posición inicial, es decir para cambiar entre una fase y otra se debe pasar
primero por la posición inicial.
Para utilizar Arduino con
LabView es necesario introducir un programa en la placa Arduino. Llamado
Lifa_Base, para que reconozca los módulos de Arduino en LabView.
Una vez hecho esto solo quedaría
asociar los botones de movimiento del motor a cada fase que le corresponde,
como cuando hice el programa en Vision Builder ya le asocie a cada imagen el
estado correspondiente y lo que debía hacer, por eso los cambios que hay que
realizar en el programa compilado en LabView son mínimos. Sin embargo, si que
tendremos que asociar la Variable Global del Contador al VI principal que
utilizaremos, y también se deben activar los boléanos de cada estado, para
poder utilizar su información en forma de indicadores en nuestro programa
principal, ya que lo que debe aparecer en el Front Panel es lo siguiente:
Contador: Debe aparecer
una pantalla en la que cada vez que se pase el boli sume o reste según proceda.
Código QR: Debe aparecer
un indicador con la dirección de la página a la que nos renvía y una ventana
con dicha página.
Texto OCR:
Debe aparecer un indicador con lo que se está leyendo en ese momento.
Por cada fase que se muestre no debe aparecer ningún
elemento de las otras fases, es decir, si estoy en la parte del contador, no debe
salir nada más que lo relevante al contador y así con las demás fases.
Ahora muestro el panel frontal nada más empezar el programa:
Lo primero que hace es intentar reconocer la cara, si no lo
consigue el resto del programa no se ejecutara.
Ahora comentare que configuraciones que realice para sacar
los indicadores de cada fase.
Para sacar un string con el valor del QR, lo que tuve que hacer
es localizar donde se encontraba el texto de la URL de la página en la parte de
Vision.
En la imagen superior, podemos
observar el panel frontal del VI correspondiente al estado “QR”, en la parte
superior hay un bloque que pone “Measurement”, es ahí donde aparece el valor
que se lee del QR, es decir la URL, sin embargo ese bloque es un array de
elementos por lo que hay que ir desplanzando columnas hasta encontrar el
elemento que corresponde al string que da el valor de la URL. En mi caso fue
para el valor 2 de índice (Ver Imagen)
Como se observa del VI
correspondiente al estado “QR” sacamos datos tipo “variant”, estos los
descomponemos en un “String Value” y sacamos el elemento que queremos y se lo
asociamos a la variable local URL que corresponde a un indicador que se
mostrara en el panel frontal del VI principal.
Para sacar el valor del texto
leído (OCR), hacemos lo mismo que para el QR
Localizamos el texto leído en el
bloque “Measurement” desplazándonos por las columnas, hasta que aparezca el
texto en la parte de “String Value”.
Y hacemos lo mismo que con el
QR, sacamos el elemento del “String Value”, que previamente sacamos del dato
tipo “variant”.
Por ultimo solo queda sacar la
parte del contador, esta parte será mucho mas sencilla ya que solo debemos
copiar la tabla que nos aparece en el bloque del estado “Contador”, en el VI de
la variable global.
En esa tabla se puede observar
que, entre otras cosas, se encuentra nuestra variable “Contador”, ahora solo
hay que saber aque posición corresponde en cuanto a fila y columna, probando
descubrimos que ese elemento que queremos se encuntra en la fila 50 de la
columna 0, asi que lo introducimos en el VI principal.
Conclusión: Esta
práctica probablemente ha sido la más difícil de todas, ya que había que
integrar diferentes partes de las prácticas realizadas durante el curso, como
son la parte de Vision junto con la programación en LabView, además de integrar
la placa Arduino. Sin embargo, dominando unos pequeños conceptos se ha podido
realizar una práctica bastante compleja que en otro ámbito de programación
igual hubiese sido mucho más difícil de realizar o haber tenido más cantidad de
conocimientos en programación.