Sei sulla pagina 1di 35

Estante multipropsito implementado al IoT.

Pablo Urgiles Leon Wong <purgilesl@est.ups.edu.ec>;Christian Pucha


Cabrera<cpuchac@est.ups.edu.ec>,Anthony Jess Yanza
Verdugo<ayanzav@est.ups.edu.ec>

Sistemas Microprocesados II;Circitos Digitales Avanzados.

Abstract. En el siguiente informe se presentar todo el procedimiento relacio-


nado con el proyecto Estante multipropsito implementado al IoT de la materia
de sistemas Microprocesados y Circuitos Digitales Avanzados, en el documento
se podr encontrar los conocimientos bsicos necesarios para realizar ste pro-
yecto, adems de los elementos electrnicos que se utilizaron con sus respectivas
caractersticas principales. Conjuntamente se colocar esquemas, programacin
y grficas utilizadas en el procedimiento de configuracin de cada uno de los
mdulos y sus dispositivos de control principales, tanto como la Raspberry y el
Arduino. Y finalmente para el lector se presentar el dispositivo terminado con
las respectivas conclusiones de los autores tanto para seguir con el avance de ste
dispositivo o su mejora en futuras generaciones..

Keywords: Raspberry, IoT, vision artificial, wifi.

1 Objetivos
1. Objetivo General
Realizar un dispositivo capaz de reconocer objetos de consumo bsico
que se encuentran en un estante y enviar los datos mediante Wi-Fi a
una aplicacin en el mvil que permita identificar la cantidad produc-
tos que se encuentran y faltantes

2. Objetivos Especficos
Diseo y Construccin del Dispositivo que simula un estante de un re-
frigerador.
Diseo y construccin de una balanza que detecte el peso de los objetos
dentro de ella mediante Arduino.
Almacenamiento de datos de los productos que se encuentran en un
refrigerador.
Reconocimiento de imagen mediante una cmara y una Raspberry.
Cuantificacin de productos mediante un sensor de proximidad.
Envo de datos va Wi-fi.
Diseo y creacin de una aplicacin en Android para comunicacin
con mdulo Wi-fi.
2 Introducin
La tecnologa a avanzado de manera desmesurada en las ltimas dcadas, sin duda al-
guna, ahora los artefactos Smart estn ocupando un gran espacio en la vida del ser
humano, por ejemplo, podemos encontrar smarphones, lavadoras inteligentes, ciudades
inteligentes Smart city, computadoras, Smart Tv. En lo que nos centramos hoy en da
es tambin en los artefactos que haran cada vez ms fcil la vida del usuario, refirin-
donos a las refrigeradoras, sin duda, el tener que ir a cada momento que falte algo en la
refrigeradora es un poco molesto, al poder implementar un sistema Smart en una re-
frigeradora, estamos permitindole al usuario tener una experiencia mucho ms placen-
tera, y no solo en ese aspecto, si no tambin, le ahorrar tiempo, ya que la refrigeradora
por s sola, le avisar al usuario cuando no haya algo que se necesite en el da a da, esto
se puede llegar a logra por medio del desarrollo de aplicaciones de Smartphone, los
cuales estn conectados al servidor de la refrigeradora y que a cada momento este se
pueda ir actualizado, cada vez que se actualice, mostrar la lista de alimentos, tales
como: carnes, lcteos, vegetales, etc. Hagan falta en el hogar, sin duda, el poder lograr
tecnologa como esta, son cosas que hoy en da dejan marca tanto en la industria como
en la complacencia del usuario.

3 Marco Terico

3.1 Arduino.
Arduino (Estados Unidos), Genuino a nivel internacional, es una compaa de hardware
libre y una comunidad tecnolgica que disea y manufactura placas computadora de
desarrollo de hardware y software, compuesta respectivamente por circuitos impresos
que integran un microcontrolador y un entorno de desarrollo (IDE), en donde se pro-
grama cada placa.

Arduino se enfoca en acercar y facilitar el uso de la electrnica y programacin de


sistemas embebidos en proyectos multidisciplinarios . Toda la plataforma, tanto para
sus componentes de hardware como de software, son liberados con licencia de cdigo
abierto que permite libertad de acceso a ellos.

El hardware consiste en una placa de circuito impreso con un microcontrolador, usual-


mente Atmel AVR, puertos digitales y analgicos de entrada/salida, , los cuales pueden
conectarse a placas de expansin (shields), que amplan las caractersticas de funciona-
miento de la placa Arduino. Asimismo, posee un puerto de conexin USB desde donde
se puede alimentar la placa y establecer comunicacin con el computador.

Por otro lado, el software consiste en un entorno de desarrollo (IDE) basado en el en-
torno de Processing y lenguaje de programacin basado en Wiring, as como en el car-
gador de arranque (bootloader) que es ejecutado en la placa. El microcontrolador de la
placa se programa mediante un computador, usando una comunicacin serial mediante
un convertidor de niveles RS-232 a TTL serial. [1]
Un arduino dispone de 14 pines que pueden configurarse como entrada o salida y a los
que puede conectarse cualquier dispositivo que sea capaz de transmitir o recibir seales
digitales de 0 y 5 V. 7

Fig. 1. Apariencia fsica de un Arduino UNO.

3.1.1 Entradas y Salidas Arduino.

Cada uno de los 14 pines digitales se puede usar como entrada o como salida. Funcionan
a 5V, cada pin puede suministrar hasta 40 mA. La intensidad mxima de entrada tam-
bin es de 40 mA.

Cada uno de los pines digitales dispone de una resistencia de pull-up interna de entre
20K y 50 K que est desconectada, salvo que nosotros indiquemos lo contrario.

Arduino tambin dispone de 6 pines de entrada analgicos que trasladan las seales a
un conversor analgico/digital de 10 bits.

Tenemos tambin pines especiales, de los cuales se encuentran los siguientes:


RX y TX: Se usan para transmisiones serie de seales TTL.
Interrupciones externas: Los pines 2 y 3 estn configurados para generar una
interrupcin en el atmega. Las interrupciones pueden dispararse cuando se en-
cuentra un valor bajo en estas entradas y con flancos de subida o bajada de la
entrada.
PWM: Arduino dispone de 6 salidas destinadas a la generacin de seales
PWM de hasta 8 bits.
SPI: Los pines 10, 11, 12 y 13 pueden utilizarse para llevar a cabo comunica-
ciones SPI, que permiten trasladar informacin full dplex en un entorno
Maestro/Esclavo.
I2C: Permite establecer comunicaciones a travs de un bus I2C. El bus I2C es
un producto de Phillips para interconexin de sistemas embebidos. Actual-
mente se puede encontrar una gran diversidad de dispositivos que utilizan esta
interfaz, desde pantallas LCD, memorias EEPROM, sensores, etc.

3.1.2 Alimentacin Arduino UNO.

Puede alimentarse directamente a travs del propio cable USB o mediante una fuente
de alimentacin externa, como puede ser un pequeo transformador o, por ejemplo una
pila de 9V. Los lmites estn entre los 6 y los 12 V. Como nica restriccin hay que
saber que si la placa se alimenta con menos de 7V, la salida del regulador de tensin a
5V puede dar menos que este voltaje y si sobrepasamos los 12V, probablemente daa-
remos la placa.

La alimentacin puede conectarse mediante un conector de 2,1mm con el positivo en


el centro o directamente a los pines Vin y GND marcados sobre la placa.

Hay que tener en cuenta que podemos medir el voltaje presente en el jack directamente
desde Vin. En el caso de que el Arduino est siendo alimentado mediante el cable USB,
ese voltaje no podr monitorizarse desde aqu.
3.1.3 Resumen de Caractersticas.

Table 1. Caractersticas principals Arduino UNO.

Microcontrolador ATmega328
Voltaje de Operacin 5V
Voltaje de Entrada (Recomendado) 7 - 12 V
Voltaje de Entrada (Lmite) 6 - 20 V
Pines de entrada-salida digital. 14 (6 pueden ser PWM)
Pines de entrada analgica. 6
Corriente continua por PIN. 40mA
Corriente continua en el PIN 3.3V 50mA
Memoria FLASH 32Kb (0.5Kb ocupados por el blootloader.
SRAM 2Kb
EEPROM 1Kb

[2]

3.2 Raspberry
Raspberry Pi es un computador de placa reducida, computador de placa nica o compu-
tador de placa simple (SBC) de bajo coste desarrollado en Reino Unido por la Funda-
cin Raspberry Pi, con el objetivo de estimular la enseanza de ciencias de la compu-
tacin en las escuelas.

Las ventas iniciales fueron del modelo B. El modelo A solo tiene un puerto USB, carece
de controlador Ethernet y cuesta menos que el modelo B, el cual tiene dos puertos USB
y controlador Ethernet 10/100. En 2014 se lanz el modelo Raspberry Pi 2 B. El ltimo
modelo lanzado en 2015 es el Raspberry Pi Zero.

A pesar que el Modelo A no tiene un puerto RJ45, se puede conectar a una red usando
un adaptador USB-Ethernet suministrado por el usuario. Por otro lado, a ambos mode-
los se puede conectar un adaptador Wi-Fi por USB, para tener acceso a redes inalm-
bricas o internet. El sistema cuenta con 256 MB de memoria RAM en su modelo A, y
con 512 MB de memoria RAM en su modelo B. Como es tpico en las computadoras
modernas, se pueden usar teclados y ratones con conexin USB compatible con Ras-
pberry Pi.

El Raspberry Pi no viene con reloj en tiempo real,5 por lo que el sistema operativo debe
usar un servidor de hora en red, o pedir al usuario la hora en el momento de arrancar el
computador. Sin embargo se podra aadir un reloj en tiempo real (como el DS1307)
con una batera mediante el uso de la interfaz I2C.

3.2.1 Software.

El Raspberry Pi usa mayoritariamente sistemas operativos GNU/Linux. Raspbian, una


distribucin derivada de Debian que est optimizada para el hardware de Raspberry Pi,
se lanz durante julio de 2012 y es la distribucin recomendada por la fundacin para
iniciarse.

Slackware ARM (tambin llamada ARMedslack) versin 13.37 y posteriores arranca


sin ninguna modificacin. Los 128-496 MiB de memoria RAM disponible en la Ras-
pberry Pi, cubren los necesarios 64 MiB de RAM para arrancar esta distribucin en
sistemas ARM y i386 sin usar interfaz grfica (el administrador de ventanas Fluxbox
que funciona bajo X Window System requiere 48 MiB de memoria RAM adicional).
Por otro lado, se estn creando distribuciones ms especficas y ligeras como IPfire
(distribucin para ser usada como firewall), u OpenELEC y OSMC (distribuciones con
el centro multimedia Kodi).

A la GPU se accede mediante una imagen del firmware de cdigo cerrado (un blob
binario, en ingls), que se carga dentro de la GPU al arrancar desde la tarjeta SD. El
archivo est asociado a los controladores del nucleo Linux que tambin son de cdigo
cerrado. Las aplicaciones hacen llamadas a las bibliotecas de tiempo de ejecucin que
son de cdigo abierto, y las mismas hacen llamadas a unos controladores de cdigo
abierto en el ncleo Linux. La API del controlador del ncleo es especfica para estas
bibliotecas. Las aplicaciones que usan vdeo hacen uso de OpenMAX, las aplicaciones
tridimensionales usan OpenGL ES y las aplicaciones 2D usan OpenVG; OpenGL ES y
OpenVG hacen uso de EGL y este ltimo, del controlador de cdigo abierto del ncleo.
[3]

3.2.2 Caractersticas

Entre las novedades ms destacadas de la Raspberry Pi 3 estn:


Procesador, un ARM Cortex A53, un procesador de cuatro ncleos a 1.2GHz
de 64 bits y que, segn sus datos, tiene un rendimiento 10 veces superior al de
la Raspberry Pi original y un 50% ms que la Raspberry Pi 2, el modelo ante-
rior.
Bluetooth 4.1 (de bajo consumo).
WiFi 802.11n integrado.
Ranura MicroSD.
Puerto USB.
Ethernet.
CPU 1.2GHz 64-bit quad-core ARMv8.
GPU Broadcom VideoCore IV, OpenGL ES 2.0, MPEG-2 y VC-1 (con licen-
cia), 1080p30 H.264/MPEG-4 AVC.
Memoria SDRAM 1 GB (compartidos con la GPU)
Entradas de video, conector MIPI CSI que permite instalar un mdulo de c-
mara desarrollado por la RPF.
Salida de video, conector RCA (PAL y NTSC), HDMI (rev1.3 y 1.4), Interfaz
DSI para panel LCD.
Salida de audio, conector de 3.5 mm, HDMI.
Consumo de 800mA (4W).
Alimentacin 5V va Micro USB o GPIO header.

[4]

Fig. 2. Apariencia fsica Raspberry PI.


3.3 Reconocimiento de Imagen
Los sistemas de computadoras son cada vez ms potentes y menos costosos, lo que
permite crear nuevas formas de arte que antes no era posible, y algunas otras formas de
arte antiguas pueden ahora verse beneficiadas con novedosas tcnicas asistidas por
computadora.

El reconocimiento de imgenes ha evolucionado a medida que mejora la tecnologa.


Puede encontrarse en numerosos campos.

Utilizando los conceptos derivados del OCR (Optical Carcter Recognition), el primer
paso para comparar dos imgenes es vectorizar cada imagen y cada cuadro para luego,
comparar las formas de los objetos resultantes.

El proceso de vectorizacin consiste en definir imgenes utilizando la geometra y fun-


ciones matemticas. Los algoritmos existentes para este proceso consumen una gran
cantidad de recursos, y la metodologa para reconocer la similitud entre estos objetos
resulta muy compleja.

La manera ms directa de comparar un cuadro la imagen original con una coleccin de


imgenes, es comparar cada pxel del cuadro de la imagen original con su correspon-
diente pxel en la imagen de la coleccin imgenes, y acumular las distancia entre cada
pareja de pxeles para determinar la distancia general entre las dos imgenes. Aunque
esta es una estrategia relativamente buena para comparar imgenes, la cantidad de com-
paraciones necesarias es muy grande. Por cada comparacin debe calcularse la distancia
entre los pxeles de las dos imgenes y por cada pareja de pxeles debe compararse cada
uno de los tres canales RGB. [5]

Fig. 3. Modelo de un reconocimiento de imagen.

3.4 Desarrollo del Reconocimiento de imagen.


Para llevar a cabo el proceso de reconocimiento de imgenes utilizamos DeepBe-
liefSDK, la herramienta desarrollada por Pete Warden aunque solo la parte relacionada
con la Raspberry Pi 3. A diferencia del uso de dicha librera en la Raspberry Pi 1 y 2,
donde la mayora de clculos matriciales que necesita la red neuronal se realizan en la
GPU (VideoCore), en el modelo 3 se pasa a utilizar la CPU. Esto se debe a que, mientras
el VideoCore sigue siendo el mismo, el nuevo procesador ARMv7 ha mejorado bastante
e incluye nuevas instrucciones. Sin embargo, el uso de la CPU no es impedimento para
realizar el proyecto, puesto que no disminuye el rendimiento y adems nos permite
utilizar el VideoCore para la visualizacin de la interfaz de usuario en la pantalla TFT.
El motivo por el que el rendimiento entre las dos placas sea muy similar, aunque utili-
cemos componentes muy distintos, es que el nuevo procesador ARMv7 cuenta con 4
ncleos que son optimizados adems con las instrucciones NEON de tipo vectorial,
frente al ARMv6 de un slo ncleo de la Raspberry Pi original. El reloj del procesador
tambin ha pasado de 700 MHz a 900 Mhz. Para sacar provecho de estas instrucciones
se utiliza a su vez la librera de C++ EIGEN, con la que se optimizan todos los clculos
de lgebra lineal, utilizando la vectorizacin explcita para las instrucciones NEON.
Esta librera no tiene ninguna dependencia, exceptuando las bibliotecas estndar.

3.4.1 Rutinas GEMM

La optimizacin de los clculos de Deep Learning en la librera DeepBeliefSDK se basa


en usar una implementacin muy eficiente de las rutinas GEMM (General Matrix to
Matrix Multiplication) en 13 cada plataforma. Estas rutinas tratan esencialmente de
multiplicar matrices de una forma eficiente sin aprovechar ninguna estructura especial
en las matrices. Para esto, en la memoria RAM las matrices deben almacenarse de forma
consecutiva, ya sea fila a fila, o columna a columna; es decir, convirtiendo la matriz en
un vector. Estas rutinas nacen como parte de la biblioteca BLAS (Basic Linear Algebra
Subrutines), creadas en 1979 para el lenguaje FORTRAN. La importancia de las rutinas
GEMM en el Deep Learning se debe a que las multiplicaciones de matrices ocupan
entre el 89 y el 95% del tiempo que necesitan las capas de la red para el reconocimiento.
Esto se debe a que una sola capa de una red tpica puede requerir la multiplicacin de
una matriz de 256 X 1152 y otra de 1152 X 192, lo que lleva un total de 57 millones de
operaciones en punto flotante. Para este proyecto, como mencionamos antes, utilizamos
la biblioteca EIGEN que implementa sus propias rutinas GEMM.

3.4.2 Instrucciones NEON

Son instrucciones de propsito general SIMD (Single Instruction, Multiple Data) de


ARM, pensadas para procesar eficientemente formatos multimedia, tales como decodi-
ficacin de vdeo, procesado de grficos 2D y 3D, procesamiento del habla, sntesis de
sonido, etc. Estas instrucciones son una extensin de los procesadores ARM Cortex,
como mencionamos anteriormente la Raspberry Pi 3 lleva el procesador ARM Cortex
A7, por lo que se aprovechan dichas instrucciones. Algunas caractersticas y formas de
funcionamiento: Los registros se consideran vectores de elementos del mismo tipo de
datos. Los tipos de datos pueden ser signed/unsigned de 8, 16, 32 o 64 bits y float con
precisin simple. Como son del tipo SIMD, se realiza la misma operacin a todos los
carriles.
3.4.3 Acciones seguidas para obtener el reconocimiento de la imagen.

Accin capturar Con la accin capturar sacamos la foto, la almacenamos y la


mostramos durante 3 segundos en la pantalla. Para esto utilizamos la librera
picamera implementada por Dave Jones con la que, cambiamos la resolucin
por defecto para poder adaptar la imagen a la pantalla TFT (320, 240) y reali-
zamos la captura. Para el algoritmo de reconocimiento no es necesario escalar
la imagen, ya que no importa el tamao, todas se reescalan en el cdigo a 256
X 256px. Para enviar la captura a la pantalla hacemos uso del comando men-
cionado anteriormente fbi (Linux Frame Buffer Image).
Accin pre visualizar Esta opcin del men simplemente nos ensea durante
4 segundos la foto que tenemos almacenada, en caso de no encontrar imagen,
se imprime un error en la pantalla. Para esta tarea utilizamos la funcin enva
foto (foto).
Accin reconocer Se trata de la accin principal del programa, en este mo-
mento es donde se realiza el reconocimiento de la imagen capturada. En primer
lugar realizamos una llamada al programa jpcnn pasndole como argumento
la foto capturada y la red neuronal a utilizar. Esta llamada escribe en un fichero
los resultados obtenidos. Todo esto lo hacemos invocando a la funcin reco-
noce (foto). Una vez tenemos el fichero resultado, con la llamada a la funcin
resultado (fichero) ordenamos el fichero con los datos, dejando en la primera
lnea el resultado con la probabilidad ms alta. Al leer la lnea aplicamos el
filtro de que la probabilidad sea mayor que 0.05, si esto se cumple imprimimos
en la pantalla el resultado obtenido. En caso de no cumplirse, se muestra un
error.

3.5 Comunicacin WI-FI


Cuando hablamos de WIFI nos referimos a una de las tecnologas de comunicacin
inlambrica mediante ondas ms utilizada hoy en da. WIFI, tambin llamada WLAN
(wireless lan, red inalmbrica) o estndar IEEE 802.11. WIFI no es una abreviatura de
Wireless Fidelity, simplemente es un nombre comercial.

En la actualidad podemos encontrarnos con dos tipos de comunicacin WIFI:

802.11b, que emite a 11 Mb/seg


802.11g, ms rapida, a 54 MB/seg

De hecho, son su velocidad y alcance (unos 100-150 metros en hardaware asequible)


lo convierten en una frmula perfecta para el acceso a internet sin cables.

Para tener una red inalmbrica en casa slo necesitaremos un punto de acceso, que se
conectara al mdem, y un dispositivo WIFI que se conectara en nuestro aparato. Exis-
ten terminales WIFI que se conectan al PC por USB, pero son las tarjetas PCI (que se
insertan directamente en la placa base) las recomendables, nos permite ahorrar espacio
fsico de trabajo y mayor rapidez. Para porttiles podemos encontrar tarjetas PCMI ex-
ternas, aunque muchos de los aparatos ya se venden con tarjeta integrada.

En cualquiera de los casos es aconsejable mantener el punto de acceso en un lugar alto


para que la recepcin/emisin sea ms fluida. Incluso si encontramos que nuestra velo-
cidad no es tan alta como debera, quizs sea debido a que los dispositivos no se en-
cuentren adecuadamente situados o puedan existir barreras entre ellos (como paredes,
metal o puertas).

El funcionamiento de la red es bastante sencillo, normalmente slo tendrs que conectar


los dispositivos e instalar su software. Muchos de los enrutadores WIFI (routers WIFI)
incorporan herramientas de configuracin para controlar el acceso a la informacin que
se transmite por el aire.

Pero al tratarse de conexiones inalmbricas, no es difcil que alguien interceptara nues-


tra comunicacin y tuviera acceso a nuestro flujo de informacin. Por esto, es recomen-
dable la encriptacin de la transmisin para emitir en un entorno seguro. En WIFI esto
es posible gracias al WPA, mucho ms seguro que su predecesor WEP y con nuevas
caractersticas de seguridad, como la generacin dinmica de la clave de acceso.

Para usuarios ms avanzados exite la posibilidad de configurar el punto de acceso para


que emita slo a ciertos dispositivos. Usando la direccin MAC, un identificador nico
de los dispositivos asignados durante su construccin, y permitiendo el acceso sola-
mente a los dispositivos instalados.

Por ltimo, tambin merece la pena comentar la existencia de comunidades wireless


que permiten el acceso gratuito a la red conectando con nodos pblicos situados en
diferentes puntos, por ejemplo, en tu ciudad. Esta tendencia an no est consolidada y
tiene un futuro impredecible, pues es muy probable que las compaas telefnicas se
interpongan a esta prctica. Si te interesa este tema y quieres ms informacin algunos
sitios de inters seran valencia wireless o RedLibre. [6]

Fig.4. Logotipo de WI-FI

3.5.1 Mdulo Esp8266.


El mdulo ESP8266 nos permite aadir conexin Wifi a nuestro Arduino por, ello nos
posibilita el control inalmbrico en un entorno de bastantes metros y sin cables, bien a
travs de nuestra red local o (si configuramos el Router y tenemos IP fija) va Internet
desde cualquier parte con un ordenador o un mvil. El mdulo mide 1,5x2,5 cm y solo
necesita dos hilos para funcionar, ya que se comunica va serie con el Arduino. No hay
una autentica comunicacin Wifi, solo es serie, pero es ms que suficiente para recibir
datos o enviar comandos a cualquiera de los pines del Arduino.

Al contrario que con el mdulo HLK-RM04 que dispone de una pgina Web para con-
figuracin, el ESP8266 se configura por medio de comandos AT.

Funciona a 3,3V y a veces consume bastante. Con una fuente de alimentacin y limi-
tando la salida a 100mA, no es capaz de arrancar. Aunque despus baja el consumo.
Los que no tengan fuente con 3,3V, pueden usar las salidas de ese voltaje de una fuente
de PC o incluso dos pilas de 1,5V en serie. [7]

Caractersticas.

CPU RISC de 32 bits: Tensilica Xtensa LX106 a 80 MHz


64 KiB de RAM de instruccin, 96 KiB de RAM de datos
Flash QSPI externo - 512 KiB a 4 MiB * (hasta 16 MiB es compatible)
IEEE 802.11 b / g / n Wi-Fi
Interruptor TR integrado, balun, LNA, amplificador de potencia y red de co-
nexin
Autenticacin WEP o WPA / WPA2 o redes abiertas
16 clavijas GPIO
SPI, IC,
Interfaces IS con DMA (compartir clavijas con GPIO)
UART en pines dedicados, adems de un UART de slo transmisin se puede
activar en GPIO2
1 ADC de 10 bits [8]

Fig.5. Mdulo ESP8266


3.6 Sensor de Peso (Celda de carga)
Una celda de carga es un transductor capaz de convertir una fuerza en una seal elc-
trica, esto la hace a travs uno o ms galgas internas que posee, configuradas en un
puente Wheatstone. Usaremos una celda de carga de 10Kg que es el valor mximo que
puede sensar. [9]
La celda de carga es una estructura diseada para soportar cargas de compresin, ten-
sin y flexin, en cuyo interior se encuentra uno o varios sensores de deformacin lla-
mados Strain Gages que detectan los valores de deformacin.
La celda de carga digital produce esta deformacin mediante circuitos wheatstone, que
actan en las bases de la mquina o sistemas de pesaje para encontrar reacciones, una
vez obtenida la resistencia, se produce la transduccin y se puede obtener el valor que
la mquina resiste.

Fig.6. Celda de carga.

Tambin son llamadas Digital Load Cell (es su traduccin en Ingls), esta se fija en la
parte donde quiere registrarse una carga que aplique un sistema mecnico. La seal de
la carga se lleva a un dispositivo electrnico, microchip o computadora central (depen-
diendo de su utilidad) para recopilar los datos totales de una o varias celdas de carga,
inclusive desarrollar anlisis estadsticos de las cargas durante un tiempo determinado
o evento en particular. [9]

3.6.1 Trasmisor de celda de carga HX711

Este mdulo es una interface entre las celdas de carga y el microcontrolador, permi-
tiendo poder leer el peso de manera sencilla. Internamente se encarga de la lectura del
puente wheatstone formado por la celda de carga, convirtiendo la lectura analgica a
digital con su conversor A/D interno de 24 bits. [10]
Es muy utilizado en procesos industriales, sistemas de medicin automatizada e indus-
tria mdica.
Se comunica con el microcontrolador mediante 2 pines (Clock y Data) de forma serial.
Fig.7. Trasmisor de celda de carga HX711

4 Desarrollo

4.1 Maqueta del Estante


El diseo de la maqueta es importante ya que se encargar en gran porcentaje de la
funcionalidad de nuestro dispositivo, en el cual se tomaron muchas cosas en cuenta, y
podemos numerar las principales.

4.1.1 Estructura Externa

La estructura externa es una caja con medidas de 41x26x23cm y la madera que la con-
forma es de 1cm de espesor. Se tom estas medidas de acuerdo a un diseo pequeo
pero adecuado para productos indispensables en el hogar, adems de tener en cuenta
que es un prototipo y sera exagerado hacerlo demasiado grande.

Fig.8. Fotografa de la Estructura externa del estante.

4.1.2 Soporte de Cmara


El soporte se lo utiliza para ajustar la cmara a un nivel ptimo en donde se pueda
ajustar la visibilidad en un rango que se pueda manejar, por eso de la colocacin de un
soporte ajustable como se observa en la siguiente figura.

Fig.9. Fotografa del soporte de cmara.

4.1.3 Estructura de la Balanza

Para la estructura que soporta el sensor de peso, est construido de forma en que la
celda de carga soporte toda la parte en donde va la balanza. De esta forma el sistema
funciona de manera ptima.
Para instalar la celda de carga hay que hacerlo con separadores, los cuales deben de
distanciar a la base y recipiente de la celda para que la parte central quede libre; adems
hay que tener en cuenta que el sentido de la flecha indica la direccin de la fuerza o
peso a aplicar. [10]
Fig.10. Fotografa de la Estructura soporte de la carga.

4.2 Balanza Electrnica.

4.2.1 Conexiones.

Conexin entre la Celda de carga y mdulo HX711

Table 2. Conexin entre la celda de varga y el mdulo.

Celda De Carga Mdulo HX711

Cable Rojo Pin E+

Cable Negro Pin E-

Cable Verde Pin A-

Cable Blanco Pin A+

Conexin entre HX711 y Arduino

Table 3. Conexin entre el mdulo y Arduino.


Mdulo Arduino UNO, MEGA,
HX711 NANO

Pin GND Pin GND

Pin DT Pin A1

Pin SCK Pin A0

Pin VCC Pin 5V

La conexin final sera como se muestra en la imagen.

Fig.11. Conexin Final al arduino.

4.2.2. Librera HX711

Explicaremos las funciones principales de esta librera.

HX711(byte PinData, byte PinClock)


Es el constructor del objeto HX711, se puede trabajar con cualquiera de los pines.

void tare(byte n);


Establece el peso actual como el peso de tara, n indica el nmero de lecturas que se
realizan para obtener la tara, por defecto n=10;

void set_scale(float scale);


Establece el valor de la escala, que es el factor de conversin para convertir valor de
lectura en un valor con unidades de peso. Por defecto es scale=1;
long read()
Espera hasta que el dispositivo est listo y devuelve la lectura del ADC del HX711

long read_average(byte n)
Realiza n veces la lectura del ADC y devuelve el promedio

double get_value(byte n)
Devuelve el valor actual restando el peso de tara. Equivalente a (read_average() -
OFFSET) . Si se especifica un valor de n, devuelve el promedio de n lecturas.

float get_units(byte n)
Devuelve el valor actual restado del peso de tara y dividido por la escala. Es equivalente
a (get_value()/SCALE). Si se especifica un valor de n, devuelve el promedio de n lec-
turas. [10]

4.2.3 Calibracin

Lo primero que se debe de hacer es calibrar, que es bsicamente hallar el valor de la


escala que se usar; es decir hallar el factor de conversin para convertir valor de lectura
en un valor con unidades de peso. La escala es diferente para cada celda y cambia de
acuerdo a la forma de instalar, al peso mximo o modelo de celda de carga, incluso as
se trate del mismo modelo de celdas no necesariamente tienen el mismo valor de escala.
Primero necesitamos conseguir un objeto con peso conocido, en otras palabras debemos
saber el peso real del objeto. Se recomienda que el peso conocido sea cercano al valor
mximo del rango de trabajo de la celda de carga. [10]

El siguiente paso es cargar el siguiente Sketch a nuestro Arduino.

#include "HX711.h"

#define DOUT A1
#define CLK A0

HX711 balanza(DOUT, CLK);

void setup() {
Serial.begin(9600);
Serial.print("Lectura del valor del ADC:t");
Serial.println(balanza.read());
Serial.println("No ponga ningun objeto sobre la balanza");
Serial.println("Destarando...");
balanza.set_scale(); //La escala por defecto es 1
balanza.tare(20); //El peso actual es considerado Tara.
Serial.println("Coloque un peso conocido:");

}
void loop() {

Serial.print("Valor de lectura: t");


Serial.println(balanza.get_value(10),0);
delay(100);
}

El programa debe correr sin el peso colocado, pues al inicio de programa calcula la tara.
Despus de poner el peso en la balanza, en el monitor serial se mostraran las lecturas
del peso, son lecturas sin escalar, por lo que les deben aparecer nmeros grandes.

Con uno o el promedio de estos datos calculamos el valor de la escala que usaremos,
para esto usaremos la siguiente formula:

El valor del peso debe estar en las unidades con las que queremos que trabaje nuestra
balanza, por ejemplo podra ser 4Kg o 4000g para Kilogramo o gramos respectiva-
mente. Entonces el valor de la Escala que usaremos es:

1757721
= = 439.43
4000

Con este dato ya obtenido pasamos a programar el sketch que vamos a utilizar para
pesar. [10]

#include "HX711.h"
#define DOUT A1
#define CLK A0

HX711 balanza(DOUT, CLK);


double aq;

void setup() {

Serial.begin(9600);
Serial.print("Lectura del valor del ADC:t");
Serial.println(balanza.read());
Serial.println("No ponga ningun objeto sobre la balanza");
Serial.println("Destarando...");
Serial.println("...");
balanza.set_scale(189.39); // Establecemos la escala balanza.tare(25);
Serial.println("Listo para pesar");
}

void loop() {
Serial.print("Peso: ");
aq=((balanza.get_units(20))*-1);

if (aq<0){
aq=0;
}

Serial.print(aq,3);
Serial.println("g");
delay(500);
}
Como se observa en el cdigo, es necesario encender el Arduino antes de colocar los
objetos que se desean pesar, de lo contrario el peso que est sobre la balanza se consi-
derar como tara. [10]

4.3 Conexin WI-FI


Para lograr esta comunicacin al Arduino se lo configur por medio de los puertos serial
del dispositivo y del mdulo Wi-Fi utilizando los comandos AT, los cuales vienen in-
cluidos en la configuracin del mdulo, los cuales sirven para configurar los diferentes
modos y funcionalidades del dispositivo. A continuacin, observaremos parte del c-
digo utilizado en la configuracin tanto serial como del mdulo.

#include <SoftwareSerial.h>
SoftwareSerial BT1(3, 2); // RX | TX

void setup()
{ Serial.begin(115200);
BT1.begin(115200);
}

void loop()
{ String B= "." ;
if (BT1.available())
{ char c = BT1.read() ;
Serial.print(c);
}
if (Serial.available())
{ char c = Serial.read();
BT1.print(c);
}
}
Para la aplicacin en el celular se utiliz una comunicacin UDP, el cual utiliza los
sockets UDP que envan los mensajes a travs del mdulo ESP8266 hacia el socket
UDP de la aplicacin que se puede visualizar en la pantalla de un Smartphone. La apli-
cacin en el celular es la siguiente.

Fig.12. Aplicacin para Android.

Una vez que le instruimos para que se conecte a nuestra WIFI, el modulo es capaz de
enviar informacin que le remitimos va la puerta serie a una direccin IP y puerto que
deseemos.
Cuando se trata de recibir, limpia todo el empaquetado TCPIP y nos reenva por la
puerta serie la informacin de datos limpia de polvo y paja, con lo que tiene la enorme
virtud de permitirnos olvidarnos de la gestin del TCPIP y de las demandas de proce-
sador y memoria que suponen.
A cambio no es exactamente una conexin WIFI, porque no tenemos acceso al stack o
al socket IP pero para el Arduino esto es casi una ventaja. [11]

4.5 Open CV (Reconocimiento).


OpenCV es una librera de Visin por Computador y Anlisis de Imagen, 100% de
cdigo libre. Con pocas lneas de cdigo es posible realizar operaciones complejas tales
cmo identificar personas en movimiento (lo cul es ideal para construir adorables
torretas automticas!), detectar objetos en movimiento y separarlos del fondo esttico,
encontrar rostros humanos en una imagen
Es multiplataforma y puede usarse en gran cantidad de lenguajes: Python, C++, C, Java
e incluso Matlab. Entre otros. [12]
OpenCV es utilizada por empresas minoritarias y poco conocidas como Google, Yahoo
e IBM [desactivando mdulos de sarcasmo]. Y por multitud de aficionados a la robtica
y makers, que gracias a su sencillez han conseguido hacer cosas realmente asombrosas.
[12]

Para la instalacin de una Raspberry PI con Raspbian:

Abrimos la Terminal y escribimos:

sudo apt-get update


sudo apt-get install libopencv-dev python-opencv

Una vez instalado, escribimos de nuevo:

sudo apt-get install libopencv-dev python-opencv

Con esto se tiene libopencv instalada.

4.5.1 Filtros Gaussinaos

Lo primero que hacemos es iniciar la cmara de la Raspberry con una resolucin con-
creta, para ir procesando cada imagen que vamos leyendo. Dibujamos un cuadrado en
la posicin de la imagen donde estar el objeto. [13]

Fig.13. Cuadro en la posicin de imagen.

A continuacin se conveirte en escala de grises:


Fig.14. Conversin a escala de grises.

Le aplicamos un filtro Gaussiano, que desenfoca la imgen de la siguiente forma: [13]

Fig.15. Aplicacin del filtro Gaussiano.

4.5.2 Segmentacin de Imagen

En OpenCV se implement un algoritmo basado en marcadores donde se especifican


cules son todos los puntos que se van a fusionar y cules no. Se trata de una segmen-
tacin de imgenes interactiva.
Lo que hacemos es dar etiquetas diferentes para nuestro objeto que conocemos. Etiqueta
la regin que estamos seguros de ser el primer plano u objeto con un color (o intensi-
dad), etiquetar la regin que estamos seguros de ser de fondo o no objeto con otro color
y, finalmente, la regin que no estamos seguros de nada, se lo etiqueta con 0. Ese es
nuestro marcador. A continuacin, se aplica el algoritmo. Entonces nuestro marcador
se actualizar con las etiquetas que dimos, y los lmites de los objetos tendrn un valor
de -1. [14]
A continuacin, usamos la Transformacin de Distancia junto con la lnea divisoria de
aguas para segmentar objetos que se tocan mutuamente.
Comenzamos con la bsqueda de una estimacin aproximada. Para eso, podemos usar
la binarizacin de Otsu.

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('coins.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.thresh-
old(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

Las regiones restantes son aquellas que no tenemos idea. Estas reas estn normalmente
alrededor de los lmites donde el primer plano y el fondo se encuentran. Lo llamamos
frontera. Puede obtenerse restando el rea sure_fg del rea sure_bg. [14]

# noise removal
kernel = np.ones((3,3),np.uint8)
opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)

# sure background area


sure_bg = cv2.dilate(opening,kernel,iterations=3)

# Finding sure foreground area


dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5)
ret, sure_fg = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0)

# Finding unknown region


sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg,sure_fg)

Empleando monedas, en la imagen de umbral, tenemos algunas regiones que estamos


seguros de las monedas y que se desprenden ahora.
Fig.16. Regiones de segmentacin.

Ahora sabemos con certeza cul es la regin de las monedas, que son de fondo y todo.
As que creamos marcador y etiquetamos las regiones dentro de ella. Las regiones que
sabemos con certeza (ya sea en primer plano o de fondo) estn etiquetados con cual-
quier entero positivo, pero enteros diferentes, y el rea que no sabemos a ciencia cierta
se queda como cero. Para ello utilizamos cv2.connectedComponents (). Marca el fondo
de la imagen con 0 y, a continuacin, los dems objetos se etiquetan con nmeros en-
teros a partir de 1. [14]

Pero sabemos que si el fondo est marcado con 0, el algoritmo lo considerar como rea
desconocida. As que queremos marcarlo con un entero diferente. En lugar de eso, mar-
caremos una regin desconocida, definida por desconocida, con 0.

# Marker labelling
ret, markers = cv2.connectedComponents(sure_fg)

# Add one to all labels so that sure background is not 0, but 1


markers = markers+1

# Now, mark the region of unknown with zero


markers[unknown==255] = 0

El resultado es mostrado en el mapa de colores JET. La regin azul oscuro muestra la


regin desconocida. Las monedas estn coloreadas con diferentes valores. El rea res-
tante que es fondo seguro se muestran en azul ms claro en comparacin con la regin
desconocida. [14]
Fig.17. Resultado en mapa de colores JET.

Entonces se modificar la imagen del marcador. La regin lmite se marcar con -1.

markers = cv2.watershed(img,markers)
img[markers == -1] = [255,0,0]

Para algunas monedas, la regin donde se tocan se segmenta adecuadamente.

Fig.18. Resultado de la segmentacin.

4.5.3 Histograma de la imagen

En las imgenes digitales un histograma de color representa el nmero de pixeles que


tienen colores en cada una de las listas fijas de rangos de colores, que se extienden sobre
el espacio de color de la imagen, es decir el conjunto de todos los posibles colores. [15]
Ahora usamos la funcin cv2.calcHist () para encontrar el histograma. Vamos a fami-
liarizarnos con la funcin y sus parmetros:

Cv2.calcHist (imgenes, canales, mscara, histSize, intervalos [, hist [, acumular]])

Imgenes: es la imagen fuente del tipo uint8 o float32. Debe ser entre corche-
tes, es decir, "[img]".
Canales: tambin se indica entre corchetes. Es el ndice del canal para el cual
calculamos el histograma. Por ejemplo, si la entrada es de escala de grises, su
valor es [0]. Para la imagen en color, puede pasar [0], [1] o [2] para calcular el
histograma del canal azul, verde o rojo, respectivamente.
Mscara: imagen de mscara. Para encontrar el histograma de imagen com-
pleta, se da como "Ninguno". Pero si quieres encontrar el histograma de una
determinada regin de la imagen, tienes que crear una imagen de mscara para
que y darlo como mscara. (Voy a mostrar un ejemplo ms tarde.)
HistSize: esto representa nuestro recuento BIN. Debe darse entre corchetes.
Para la escala completa, pasamos [256].
Gamas: esta es nuestra GAMA. Normalmente, es [0,256].

Comencemos con una imagen de muestra. Basta con cargar una imagen en el modo de
escala de grises y encontrar su histograma completo. [15]

Img = cv2.imread ('home.jpg', 0)


Hist = cv2.calcHist ([img], [0], Ninguno, [256], [0,256])

Hist es una matriz 256x1, cada valor corresponde al nmero de pxeles en esa imagen
con su valor de pxel correspondiente.
Se obtiene lo siguiente:

Fig.19. Histograma completo en base a la escala de grises.


Se puede utilizar trama normal de matplotlib, que sera bueno para la trama BGR. Para
ello, primero debe buscar los datos del histograma.

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('home.jpg')
color = ('b','g','r')
for i,col in enumerate(color):
histr = cv2.calcHist([img],[i],None,[256],[0,256])
plt.plot(histr,color = col)
plt.xlim([0,256])
plt.show()

Lo que resulta en:

Fig.20. Altos valores de la imagen.

Usamos cv2.calcHist () para encontrar el histograma de la imagen completa. Si se desea


encontrar histogramas en solo unas regiones de la imagen, basta con crear una imagen
de mscara con color blanco en la regin que desea encontrar el histograma y negro de
lo contrario.

img = cv2.imread('home.jpg',0)

# create a mask
mask = np.zeros(img.shape[:2], np.uint8)
mask[100:300, 100:400] = 255
masked_img = cv2.bitwise_and(img,img,mask = mask)

# Calculate histogram with mask and without mask


# Check third argument for mask
hist_full = cv2.calcHist([img],[0],None,[256],[0,256])
hist_mask = cv2.calcHist([img],[0],mask,[256],[0,256])
plt.subplot(221), plt.imshow(img, 'gray')
plt.subplot(222), plt.imshow(mask,'gray')
plt.subplot(223), plt.imshow(masked_img, 'gray')
plt.subplot(224), plt.plot(hist_full), plt.plot(hist_mask)
plt.xlim([0,256])

plt.show()

En el grfico del histograma, la lnea azul muestra el histograma de la imagen completa


mientras que la lnea verde muestra el histograma de la regin enmascarada.

Fig.20. Grfico del histograma aplicando mascaras.

4.5.4 Generacin de base de datos de imgenes de prueba.

Finalmente se genera un cdigo empleando todo lo visto anteriormente. Para la seg-


mentacin y el reconocimiento de las palabras. Empleando cdigo ASCII se logra el
cometido del reconocimiento de letras.

El cdigo empleado es el siguiente:

# TrainAndTest.py
import cv2

import numpy as np

import operator

import os

# module level variables


#####################################################################

MIN_CONTOUR_AREA = 100

RESIZED_IMAGE_WIDTH = 20

RESIZED_IMAGE_HEIGHT = 30

#####################################################################
##############################

class ContourWithData():

# member variables
#####################################################################
#######

npaContour = None # contour

boundingRect = None # bounding rect for contour

intRectX = 0 # bounding rect top left corner x location

intRectY = 0 # bounding rect top left corner y location

intRectWidth = 0 # bounding rect width

intRectHeight = 0 # bounding rect height

fltArea = 0.0 # area of contour

def calculateRectTopLeftPointAndWidthAndHeight(self): # calculate bounding rect

[intX, intY, intWidth, intHeight] = self.boundingRect

self.intRectX = intX

self.intRectY = intY
self.intRectWidth = intWidth

self.intRectHeight = intHeight

def checkIfContourIsValid(self): # this is oversimplified, for grade program

if self.fltArea < MIN_CONTOUR_AREA: return False # much better validity


checking would be necessary

return True

#####################################################################
##############################

def main():

allContoursWithData = [] # declare empty lists,

validContoursWithData = [] # we will fill these shortly

try:

npaClassifications = np.loadtxt("classifications.txt", np.float32) # read in classi-


fications

except:

print "error, unable to open classifications.txt, exiting program\n"

os.system("pause")

return

# end try

try:

npaFlattenedImages = np.loadtxt("flattened_images.txt", np.float32)

# read in training images

except:

print "error, unable to open flattened_images.txt, exiting program\n"

os.system("pause")

return

# end try
npaClassifications = npaClassifications.reshape((npaClassifications.size, 1)) # re-
shape numpy array to 1d, necessary to pass to call to train

kNearest = cv2.ml.KNearest_create() # instantiate KNN object

kNearest.train(npaFlattenedImages, cv2.ml.ROW_SAMPLE, npaClassifications)

imgTestingNumbers = cv2.imread("test1.png") # read in testing numbers im-


age

if imgTestingNumbers is None: # if image was not read success-


fully

print "error: image not read from file \n\n" # print error message to std out

os.system("pause") # pause so user can see error message

return # and exit function (which exits program)

# end if

imgGray = cv2.cvtColor(imgTestingNumbers, cv2.COLOR_BGR2GRAY) # get


grayscale image

imgBlurred = cv2.GaussianBlur(imgGray, (5,5), 0) # blur

# filter image from grayscale to black and white

imgThresh = cv2.adaptiveThreshold(imgBlurred, # input image

255, # make pixels that pass the threshold


full white

cv2.ADAPTIVE_THRESH_GAUSSIAN_C, # use gauss-


ian rather than mean, seems to give better results

cv2.THRESH_BINARY_INV, # invert so fore-


ground will be white, background will be black

11, # size of a pixel neighborhood used


to calculate threshold value

2) # constant subtracted from the mean


or weighted mean

imgThreshCopy = imgThresh.copy() # make a copy of the thresh image, this in


necessary b/c findContours modifies the image
imgContours, npaContours, npaHierarchy = cv2.findContours(imgThreshCopy,
# input image, make sure to use a copy since the function will modify this image in
the course of finding contours

cv2.RETR_EXTERNAL, # retrieve the outermost contours only

cv2.CHAIN_APPROX_SIMPLE) # compress horizontal, vertical, and diagonal seg-


ments and leave only their end points

for npaContour in npaContours: # for each contour

contourWithData = ContourWithData() # instantiate a contour with data object

contourWithData.npaContour = npaContour # assign contour with data

contourWithData.boundingRect = cv2.boundingRect(contourWithData.npaCon-
tour) # get the bounding rect

contourWithData.calculateRectTopLeftPointAndWidthAndHeight()
# get bounding rect info

contourWithData.fltArea = cv2.contourArea(contourWithData.npaContour)
# calculate the contour area

allContoursWithData.append(contourWithData) # add
contour with data object to list of all contours with data

# end for

for contourWithData in allContoursWithData: # for all contours

if contourWithData.checkIfContourIsValid(): # check if valid

validContoursWithData.append(contourWithData)

# end if

# end for

validContoursWithData.sort(key = operator.attrgetter("intRectX")) # sort con-


tours from left to right
strFinalString = "" # declare final string, this will have the final number se-
quence by the end of the program

for contourWithData in validContoursWithData: # for each contour

# draw a green rect around the current char

cv2.rectangle(imgTestingNumbers, # draw rectangle on original image

(contourWithData.intRectX, contourWithData.intRectY),
(contourWithData.intRectX + contourWithData.intRectWidth, contour-
WithData.intRectY + contourWithData.intRectHeight), # lower right cor-
ner

(0, 255, 0), # green

2) # thickness

imgROI = imgThresh[contourWithData.intRectY : contourWithData.intRectY +


contourWithData.intRectHeight, # crop char out of threshold image

contourWithData.intRectX : contourWithData.intRectX + contourWithData.in-


tRectWidth]

imgROIResized = cv2.resize(imgROI, (RESIZED_IMAGE_WIDTH,


RESIZED_IMAGE_HEIGHT)) # resize image, this will be more consistent
for recognition and storage

npaROIResized = imgROIResized.reshape((1, RESIZED_IMAGE_WIDTH *


RESIZED_IMAGE_HEIGHT)) # flatten image into 1d numpy array

npaROIResized = np.float32(npaROIResized) # convert from 1d numpy ar-


ray of ints to 1d numpy array of floats

retval, npaResults, neigh_resp, dists = kNearest.findNearest(npaROIResized, k =


1) # call KNN function find_nearest

strCurrentChar = str(chr(int(npaResults[0][0]))) # get character from results

strFinalString = strFinalString + strCurrentChar # append current char to


full string

# end for
print "\n" + strFinalString + "\n" # show the full string

cv2.imshow("imgTestingNumbers", imgTestingNumbers) # show input image


with green boxes drawn around found digits

cv2.waitKey(0) # wait for user key press

cv2.destroyAllWindows() # remove windows from memory

return

#####################################################################
##############################

if __name__ == "__main__":

main()

# end if

Conclusiones
El proyecto se lo realiz pensando en las mltiples utilidades que le vendran bien a un
estante que reconozca objetos o etiquetas. Principalmente pueden ser innumerables de-
pendiendo de la imaginacin del usuario y de la perspicacia del programador. Puede
utilizarse para reconocer alimentos en un refrigerador, elementos de medicina en una
farmacia o simplemente insumos de cocina o alimenticios. Todo esto es gracias a que
puede comunicarse por medio de una aplicacin hacia un dispositivo Android y dar a
conocer los valores del peso as como el reconocimiento de letras, colores o imgenes
para distinguir los objetos en el interior del estante. Cabe recalcar que el procedimiento
necesario para su funcionamiento fue muy largo y tedioso ya que no existen mucha
informacin en espaol de la manera de trabajar con la visin artificial o en nuestro pas
no se ha inmerso lo suficiente en esta tecnologa

References
1. https://es.wikipedia.org/wiki/Arduino
2. http://www3.gobiernodecanarias.org/medusa/ecoblog/ralvgon/files/2013/05/Carac-
ter%C3%Assticas-Arduino.pdf
3. https://es.wikipedia.org/wiki/Raspberry_Pi
4. http://www.omicrono.com/2016/02/raspberry-pi-3-model-b/
5. Captulo IX Reconocimiento de Imgenes y Caracteres - Daisy Elizabeth Imbaquingo Es-
parza.
6. http://www.aulaclic.es/articulos/wifi.html
7. Wifi para Arduino con ESP8266, disponible en: http://83.56.32.125/esp8266.html
8. https://en.wikipedia.org/wiki/ESP8266
9. Ing. Moises Espinoza (Marzo de 1995). Diseo y construccin de una celda de carga.
Consultado el 1 de febrero de 2016.
10. http://www.naylampmechatronics.com/blog/25_Tutorial-trasmisor-de-celda-de-carga-
HX711-Ba.html
11. http://www.prometec.net/arduino-wifi/
12. hhttp://robologs.net/2014/04/25/instalar-opencv-en-raspberry-pi-2/
13. https://raistech.wordpress.com/tag/opencv-en-raspberry-pi/
14. http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_wa-
tershed/py_watershed.html
15. http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_histo-
grams/py_histogram_begins/py_histogram_begins.html#histograms-getting-started

Potrebbero piacerti anche