Aide anti-gaspillage alimentaire : Différence entre versions
(→Librairie Cropper) |
|||
(25 révisions intermédiaires par 2 utilisateurs non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
+ | <include nopre noesc src="/home/pedago/pimasc/include/video-Gaspillage-iframe.html" /> | ||
+ | __TOC__ | ||
+ | <br style="clear: both;"/> | ||
==Présentation générale== | ==Présentation générale== | ||
Ligne 38 : | Ligne 41 : | ||
==Réalisation== | ==Réalisation== | ||
− | ===Traitement de l'étiquette=== | + | ====Traitement de l'étiquette==== |
Pour récupérer les informations nécessaires sur l'étiquette, nous devons utiliser un outil de traitement d'image capable de reconnaître et séparer les caractères. | Pour récupérer les informations nécessaires sur l'étiquette, nous devons utiliser un outil de traitement d'image capable de reconnaître et séparer les caractères. | ||
Ligne 51 : | Ligne 54 : | ||
[[Fichier:RFduino.jpg|200px|thumb|right|RFduino utilisé]] | [[Fichier:RFduino.jpg|200px|thumb|right|RFduino utilisé]] | ||
− | === | + | |
+ | ===Boîtier électronique=== | ||
Le meilleur outil nous permettant de communiquer via Bluetooth et de stocker les données est un '''RFduino'''. | Le meilleur outil nous permettant de communiquer via Bluetooth et de stocker les données est un '''RFduino'''. | ||
Ligne 66 : | Ligne 70 : | ||
===Application Android=== | ===Application Android=== | ||
− | Les applications Android utilisent essentiellement du '''Java''' et ''' | + | Les applications Android utilisent essentiellement du '''Java''' et '''SQLite'''. N'ayant jamais fait de Java, nous nous familiarisons avec le langage afin de proposer une application complète. |
Elle se présentera sous la forme : | Elle se présentera sous la forme : | ||
Ligne 86 : | Ligne 90 : | ||
====Librairie Cropper==== | ====Librairie Cropper==== | ||
− | Pour ne séléctionner que la zone de texte qui nous | + | Pour ne séléctionner que la zone de texte qui nous intéresse, l'idée première fût d'utiliser l'Action Android "Crop", |
actionnable depuis un Intent : | actionnable depuis un Intent : | ||
<pre> | <pre> | ||
− | + | // Appel l'intent crop action | |
Intent cropIntent = new Intent("com.android.camera.action.CROP"); | Intent cropIntent = new Intent("com.android.camera.action.CROP"); | ||
− | + | // Indique le type de fichier et son URI | |
cropIntent.setDataAndType(picUri, "image/*"); | cropIntent.setDataAndType(picUri, "image/*"); | ||
− | + | // Ajoute la fonction crop à l'intent | |
cropIntent.putExtra("crop", "true"); | cropIntent.putExtra("crop", "true"); | ||
− | + | // Indique le ratio du crop | |
cropIntent.putExtra("aspectX", 1); | cropIntent.putExtra("aspectX", 1); | ||
cropIntent.putExtra("aspectY", 1); | cropIntent.putExtra("aspectY", 1); | ||
Ligne 103 : | Ligne 107 : | ||
cropIntent.putExtra("outputY", 256); | cropIntent.putExtra("outputY", 256); | ||
− | + | //Permet de récuperer la data en sortie | |
cropIntent.putExtra("return-data", true); | cropIntent.putExtra("return-data", true); | ||
− | + | //Lance l'activité, qui se récupère dans la fonction onActivityResult | |
startActivityForResult(cropIntent, PIC_CROP); | startActivityForResult(cropIntent, PIC_CROP); | ||
</pre> | </pre> | ||
+ | |||
+ | Cette solution comporte 3 problèmes : | ||
+ | * Seules les téléphones disposant de l'action Crop peuvent utiliser l'Intent. | ||
+ | * En fonction des modèles, l'action ne réalise pas le même travail. | ||
+ | * Un ratio doit être fixé au préalable pour définir la taille de sortie. | ||
+ | |||
+ | La librairie Cropper nous as permis d'outrepasser tout ces problèmes et nous permet d'avoir une action de découpe très puissante. | ||
+ | La librairie propose différente forme de base de découpe (Carré, Rectangle, Cercle...) | ||
+ | le ratio n'est pas fixe et peut être régler au doigts une fois la photo prise. | ||
+ | |||
+ | ====Webview==== | ||
+ | |||
+ | Ayant remarqué que le site http://www.lebruitdufrigo.fr/ permet de trouver des recettes par ingrédient, on a mis en place une Webview. | ||
+ | |||
+ | La Webview charge le site en rajoutant les ingrédients grâce à la méthode GET. | ||
+ | |||
+ | L'idée est de créer une chaîne de caractère où chaque ingrédient est séparé par le caractère '+'. | ||
+ | |||
+ | Le site web se charge du reste. | ||
+ | |||
+ | <pre> | ||
+ | String str = _field2.getText().toString(); // _field2 : InputText a titre d'essai, zone de texte pour les ingrédients | ||
+ | str.toLowerCase(); // On convertit les caractère en minuscule | ||
+ | str.replace(' ', '+'); | ||
+ | setContentView(R.layout.activity_webview); // Lance l'activité Webview | ||
+ | |||
+ | webview = (WebView) findViewById(R.id.webview); | ||
+ | webview.getSettings().setJavaScriptEnabled(true); | ||
+ | webview.getSettings().setLoadWithOverviewMode(true); | ||
+ | webview.getSettings().setUseWideViewPort(true); | ||
+ | webview.loadUrl("http://www.lebruitdufrigo.fr/recettes.php?rechClassique=" + str); | ||
+ | </pre> | ||
+ | |||
+ | ====Base de Donnée==== | ||
+ | |||
+ | Afin de sauvegarder la liste de produit, on utilise la Base de donnée SQLite très bien implémenté sur Android. | ||
+ | La donnée stocké est plutôt simple : | ||
+ | |||
+ | <pre> | ||
+ | '''Ingredient''' | ||
+ | String Description | ||
+ | String DLC | ||
+ | String Date_maj | ||
+ | </pre> | ||
+ | Cette table est donc une copie de la ligne sauvegarder sur le RFduino. | ||
===Protocole d'échange BLE=== | ===Protocole d'échange BLE=== | ||
Ligne 116 : | Ligne 165 : | ||
*2. Le fichier 'Frigidee.txt' sera ordonné chronologiquement, la date d'ajout est un paramètre transmit. | *2. Le fichier 'Frigidee.txt' sera ordonné chronologiquement, la date d'ajout est un paramètre transmit. | ||
− | Une ligne se compose ainsi ''' | + | Une ligne se compose ainsi '''DateMAJ#designation#DatePeremeption'''. |
− | Avec | + | |
+ | Avec DateMAJ: la date d'ajout de l'élément sur le RFduino de la forme yymmddhhmm | ||
designation, la chaîne de caractère visible par l'utilisateur désignant le produit en question MAX = 30 caractères. | designation, la chaîne de caractère visible par l'utilisateur désignant le produit en question MAX = 30 caractères. | ||
− | + | DatePeremption, la date de péremption du produit de la forme yymmdd | |
'''UPDATE''' | '''UPDATE''' | ||
La consigne Update permet de mettre à jour le Smartphone avec la liste présente sur le module Bluetooth. On envoie une chaîne de caractères " X " sur le RFDuino, indiquant la date d'ajout du dernier élément de la liste. Le RFDuino répond ensuite avec la liste partiel depuis la date correspondant à X jusqu’à la fin de fichier. | La consigne Update permet de mettre à jour le Smartphone avec la liste présente sur le module Bluetooth. On envoie une chaîne de caractères " X " sur le RFDuino, indiquant la date d'ajout du dernier élément de la liste. Le RFDuino répond ensuite avec la liste partiel depuis la date correspondant à X jusqu’à la fin de fichier. | ||
+ | |||
+ | <pre> | ||
+ | update( DATE_SMARTPHONE ) | ||
+ | { | ||
+ | FAIRE | ||
+ | LIRE ligne; | ||
+ | TANT QUE (DATE_SMARTPHONE est_plus_récente_que DATE_MICROP) | ||
+ | SI (DATE_SMARTPHONE n'est pas plus récente que DATE_MICROP) | ||
+ | ENVOYER fin du texte par série | ||
+ | FIN SI | ||
+ | } | ||
+ | </pre> | ||
'''RETRAIT''' | '''RETRAIT''' | ||
− | On envoie | + | |
+ | On envoie une désignation sur le RFduino, il parcours ensuite le fichier afin de repérer la ligne en question. | ||
Nous ne savons pas encore, pour le retrait d'une ligne, si nous allons repérer la ligne en question est récrire par dessus avec le reste du fichier. | Nous ne savons pas encore, pour le retrait d'une ligne, si nous allons repérer la ligne en question est récrire par dessus avec le reste du fichier. | ||
Ou réécrire dans un autre fichier en omettant la ligne en question. | Ou réécrire dans un autre fichier en omettant la ligne en question. | ||
− | N.B : Deux proposition s'offrent à nous, ou on | + | N.B : Deux proposition s'offrent à nous, ou on réécrit la suite de la liste sur la ligne à supprimer, ou bien, on copie dans un autre fichier en omettant la ligne en question. |
[EDIT n°1] | [EDIT n°1] | ||
Ligne 165 : | Ligne 228 : | ||
===Semaine 07=== | ===Semaine 07=== | ||
− | * | + | *Réalisation de la fonction retrait |
+ | |||
+ | ===Semaine 08=== | ||
+ | *Réalisation de la fonction update | ||
+ | |||
+ | ===Semaine 09=== | ||
+ | *Debuggage .c du RFduino (ajout/update) | ||
+ | *Import de la bibliothèque Cropper. | ||
+ | |||
+ | ===Semaine 10=== | ||
+ | *Réunification des différentes bibliothèques au sein de la même activité Photo => Crop => OCR ! | ||
+ | |||
+ | |||
+ | ==Rendu== | ||
+ | |||
+ | SOURCES : [[Fichier:Projet_P29_sources.zip]] | ||
+ | |||
+ | RAPPORT : [[Fichier:Rapport_de_projet_-_FITOUSSI-GIOVANNANGELI.pdf]] | ||
+ | Vidéo : [https://drive.google.com/folderview?id=0B5oFs145NHiZYkpJeE1xUFZPemM&usp=sharing Google Drive] | ||
''Projet IMA4 réalisé par Pierre FITOUSSI et Florian GIOVANNANGELI - Promotion 2017 (vous êtes surs ?)'' | ''Projet IMA4 réalisé par Pierre FITOUSSI et Florian GIOVANNANGELI - Promotion 2017 (vous êtes surs ?)'' |
Version actuelle datée du 15 juin 2016 à 07:58
Présentation générale
Contexte
Dans une époque où on estime à environ 1,3 milliards de tonnes de denrées alimentaires par an, soit un tiers des aliments produits pour la consommation humaine, perdues ou gaspillées, il apparaît nécessaire de mettre en place des outils permettant d'éviter de laisser un ingrédient acheté se périmer au fond du réfrigérateur.
Cahier des charges
Intitulé
L'objectif de ce projet est de proposer une application capable de scanner l'étiquette d'un produit et d'enregistrer plusieurs informations, comme la date de péremption, dans une base de données fixée au réfrigérateur. Cela permettra de prévenir l'utilisateur lorsque l'un de ses produits est proche de la date limite et qu'il doit être consommé. On pourra également proposer un moteur de recherche (marmiton.org par exemple) afin de suggérer des recettes en se basant sur les aliments dont l'utilisateur dispose.
Objectifs
Pour atteindre l'objectif du projet, les étapes suivantes sont nécessaires :
- Utilisation de la caméra d'un smartphone pour scanner l'étiquette par prise de photo, voire peut-être en flux continu.
- Traitement d'image afin de récupérer et trier les données de l'étiquette.
- Rapatriement des données sur un boitier électronique (serveur) fixé au réfrigérateur, via Bluetooth.
- Création d'application Android regroupant les différents services proposés.
Choix techniques : matériel et logiciel
Pour la réalisation du projet, peu de matériel est nécessaire mais de bonnes connaissance en traitement d'image et programmation Java/C/XML sont grandement requises.
Matériel nécessaire :
- Boitier électronique avec :
- Arduino ou Raspberry pour la communication et l'archivage des données
- Leds (état de fonctionnement/communication)
- Système de fixation sur réfrigérateur
- Système d'alimentation
- Un Smartphone / Tablette Android (client)
Pour la réalisation du prototype de ce projet, nous nous focaliserons sur la récupération d'information et sur la synchronisation/archivage des données entre Smartphone et Arduino. Le boitier, son esthétique/fonctionnalité et le système de fixation peuvent être réalisés plus tard.
Réalisation
Traitement de l'étiquette
Pour récupérer les informations nécessaires sur l'étiquette, nous devons utiliser un outil de traitement d'image capable de reconnaître et séparer les caractères. Nous avons donc choisi d'utiliser le moteur de reconnaissance de caractère tesseract. Nous allons ensuite l'adapter à la prise de photo via la caméra d'un Smartphone ou tablette.
A l'heure actuelle, nous nous occupons du programme qui triera et stockera les informations récupérées par tesseract dans une base de données sous la forme :
- Description du produit
- Date limite de consommation
Boîtier électronique
Le meilleur outil nous permettant de communiquer via Bluetooth et de stocker les données est un RFduino.
Nous en avons donc récupéré un et commençons à étudier son fonctionnement pour l'adapter au programme et aux fonctions voulues. L'idéal serait de trouver le moyen de l'alimenter sans fil pour le fixer facilement au réfrigérateur. D'après nos recherches, ce genre de système d'alimentation pour RFduino existe ou est réalisable. En fonction de l'action demandé sur le téléphone (Ajout d'un nouveau produit ou bien un retrait), on édite un fichier "frigidee.txt" présent sur la carte SD du RFduino.
Application Android
Les applications Android utilisent essentiellement du Java et SQLite. N'ayant jamais fait de Java, nous nous familiarisons avec le langage afin de proposer une application complète.
Elle se présentera sous la forme :
- Un écran d'accueil avec 3 onglets :
- Connexion (pour connecter l'appareil avec le boîtier électronique fixé au réfrigérateur)
- Liste des ingrédients (afin de limiter les transferts d'information, le boîtier enverra à l'application seulement les 6 ingrédients ayant la plus proche DLC)
- Recettes (permettant de trouver des recettes via marmiton.org ou autre avec les ingrédients à disposition)
Librairie Tesseract
Afin de reconnaître une étiquette, nous avons utiliser un fork de la bibliotheque Tesseract. Developper pour être utiliser sur Android, grace au NDK de google, elle nous permet de de créer une chaîne de caractère à partir d'une image.
Malheureusement, à moins de ne prendre en photo que la zone de texte, le moteur Tesseract interprète des caractères non présents. Il est donc nécessaire de rajouter un cadre de sélection afin de redécouper l'image.
Librairie Cropper
Pour ne séléctionner que la zone de texte qui nous intéresse, l'idée première fût d'utiliser l'Action Android "Crop", actionnable depuis un Intent :
// Appel l'intent crop action Intent cropIntent = new Intent("com.android.camera.action.CROP"); // Indique le type de fichier et son URI cropIntent.setDataAndType(picUri, "image/*"); // Ajoute la fonction crop à l'intent cropIntent.putExtra("crop", "true"); // Indique le ratio du crop cropIntent.putExtra("aspectX", 1); cropIntent.putExtra("aspectY", 1); cropIntent.putExtra("outputX", 256); cropIntent.putExtra("outputY", 256); //Permet de récuperer la data en sortie cropIntent.putExtra("return-data", true); //Lance l'activité, qui se récupère dans la fonction onActivityResult startActivityForResult(cropIntent, PIC_CROP);
Cette solution comporte 3 problèmes :
- Seules les téléphones disposant de l'action Crop peuvent utiliser l'Intent.
- En fonction des modèles, l'action ne réalise pas le même travail.
- Un ratio doit être fixé au préalable pour définir la taille de sortie.
La librairie Cropper nous as permis d'outrepasser tout ces problèmes et nous permet d'avoir une action de découpe très puissante. La librairie propose différente forme de base de découpe (Carré, Rectangle, Cercle...) le ratio n'est pas fixe et peut être régler au doigts une fois la photo prise.
Webview
Ayant remarqué que le site http://www.lebruitdufrigo.fr/ permet de trouver des recettes par ingrédient, on a mis en place une Webview.
La Webview charge le site en rajoutant les ingrédients grâce à la méthode GET.
L'idée est de créer une chaîne de caractère où chaque ingrédient est séparé par le caractère '+'.
Le site web se charge du reste.
String str = _field2.getText().toString(); // _field2 : InputText a titre d'essai, zone de texte pour les ingrédients str.toLowerCase(); // On convertit les caractère en minuscule str.replace(' ', '+'); setContentView(R.layout.activity_webview); // Lance l'activité Webview webview = (WebView) findViewById(R.id.webview); webview.getSettings().setJavaScriptEnabled(true); webview.getSettings().setLoadWithOverviewMode(true); webview.getSettings().setUseWideViewPort(true); webview.loadUrl("http://www.lebruitdufrigo.fr/recettes.php?rechClassique=" + str);
Base de Donnée
Afin de sauvegarder la liste de produit, on utilise la Base de donnée SQLite très bien implémenté sur Android. La donnée stocké est plutôt simple :
'''Ingredient''' String Description String DLC String Date_maj
Cette table est donc une copie de la ligne sauvegarder sur le RFduino.
Protocole d'échange BLE
RFduino nous permet d'utiliser des fonctions déjà présentes sur les librairies cela nous facilite le travail et nous permet de facilement transmettre des caractères entre les deux systèmes.
- 1. Le Smartphone enverra une première trame 'Action' qui aura 3 formes : 'Update', 'Retrait' et 'Ajout'.
- 2. Le fichier 'Frigidee.txt' sera ordonné chronologiquement, la date d'ajout est un paramètre transmit.
Une ligne se compose ainsi DateMAJ#designation#DatePeremeption.
Avec DateMAJ: la date d'ajout de l'élément sur le RFduino de la forme yymmddhhmm designation, la chaîne de caractère visible par l'utilisateur désignant le produit en question MAX = 30 caractères. DatePeremption, la date de péremption du produit de la forme yymmdd
UPDATE
La consigne Update permet de mettre à jour le Smartphone avec la liste présente sur le module Bluetooth. On envoie une chaîne de caractères " X " sur le RFDuino, indiquant la date d'ajout du dernier élément de la liste. Le RFDuino répond ensuite avec la liste partiel depuis la date correspondant à X jusqu’à la fin de fichier.
update( DATE_SMARTPHONE ) { FAIRE LIRE ligne; TANT QUE (DATE_SMARTPHONE est_plus_récente_que DATE_MICROP) SI (DATE_SMARTPHONE n'est pas plus récente que DATE_MICROP) ENVOYER fin du texte par série FIN SI }
RETRAIT
On envoie une désignation sur le RFduino, il parcours ensuite le fichier afin de repérer la ligne en question. Nous ne savons pas encore, pour le retrait d'une ligne, si nous allons repérer la ligne en question est récrire par dessus avec le reste du fichier. Ou réécrire dans un autre fichier en omettant la ligne en question.
N.B : Deux proposition s'offrent à nous, ou on réécrit la suite de la liste sur la ligne à supprimer, ou bien, on copie dans un autre fichier en omettant la ligne en question.
[EDIT n°1] La fonction recherche se décomposent en 2 programmes, le premier sert à repérer la ligne en question. La deuxième créer un fichier temporaire dans lequelle on copie les lignes précedants la ligne concerné, saute la ligne a supprimer et copie le reste du fichier. Le fichier temporaire est ensuite reparcouru pour recopier la liste dans le fichier original.
Avancement du projet
Semaine 01
- Recherche sur la reconnaissance visuelle => première piste OpenCV
- Documentation sur le langage Java et dérivé pour Android
Semaine 02
- Abandon d'OpenCV pour l'utilisation de la librairie Tesseract-OCR (Multi langage)
- Test du Paquet Tesseract-OCR sur une plate-forme Linux => Non concluant
Semaine 03
- Test avec résultat intéressant d'une image .jpg, le moteur retourne bien une chaîne de caractère
- La rotation de l'image est incluse dans le soft mais option à préciser
Semaine 04
- Initiation à l'IDE Android-Studio
- Import de la bibliothèque Tess-Two dérivé de Tesseract pour mobile
Semaine 05
- Rendez-vous de mi-parcours
- Cahier des charges revisité
- Documentation sur le RFduino
Semaine 06
- Réalisation des fonctions d'ajout, de parcours du fichiers en vu des commande update et retrait
- Conception d'un squelette d'application Android
Semaine 07
- Réalisation de la fonction retrait
Semaine 08
- Réalisation de la fonction update
Semaine 09
- Debuggage .c du RFduino (ajout/update)
- Import de la bibliothèque Cropper.
Semaine 10
- Réunification des différentes bibliothèques au sein de la même activité Photo => Crop => OCR !
Rendu
SOURCES : Fichier:Projet P29 sources.zip
RAPPORT : Fichier:Rapport de projet - FITOUSSI-GIOVANNANGELI.pdf
Vidéo : Google Drive
Projet IMA4 réalisé par Pierre FITOUSSI et Florian GIOVANNANGELI - Promotion 2017 (vous êtes surs ?)