Partie technique Pharmalog

De Learning Lab Environnements Connectés
Révision datée du 12 mai 2015 à 10:24 par Sebastien B. (discussion | contributions) (nouvelle rubrique auto)
Sauter à la navigation Sauter à la recherche

Matériel utilisé

Lors de ce workshop nous avons utilisé une carte électronique Raspberry Pi 2-Model B. Il était nécessaire de détecter un QR-code. Pour cela nous avons décidé d'utiliser une Raspberry Pi Camera Board et donc une détection via module vidéo.

Tutoriel pas à pas

  • Pré-requis : matériel cité plus haut. Un écran et un clavier et une connexion internet.
  • Pour commencer il faut installer un système d'exploitation sur votre Raspberry. Lors de notre projet nous avons utilisé The Thing Box comme système d'exploitation mais un système classique Raspbian est suffisant.

Pour savoir comment l'installer voir ici : http://thethingbox.io/docs/Flash_Pi_image.html

  • Une fois le système installer il faut alors installer la Raspicam. Pour cela vérifier que votre système est à jour :

sudo apt-get update sudo apt-get upgrade Il faut ensuite ouvrir et menu de configuration et passer sur "enable" la camera. Pour accéder au menu config : sudo raspi-config

  • Maintenant il faut installer zbar. Pour cela suivez les étapes suivantes :

sudo apt-get install python-gtk2-dev wget http://sourceforge.net/projects/zbar/files/zbar/0.10/zbar-0.10.tar.bz2/download -O zbar-0.10.tar.bz2 bunzip2 zbar-0.10.tar.bz2 tar -xvf zbar-0.10.tar mkdir -v zbar-build cd zbar-build ../zbar-0.10/configure \

   --prefix=/usr/local \
   --disable-video \
   --without-imagemagick

make make check sudo make install Il faut ensuite modifier le fichier zbar.conf sudo nano /etc/ld.so.conf.d/zbar.conf et ajouter la ligne : /usr/local/lib

Puis on termine par la prise en compte de nos modifications : sudo ldconfig

Je précise que pour cette étape l'installation va être fonction de votre modèle de Raspberry. Le tutu donné utilise une Raspberry B premier modèle. Avec la Raspberry 2 l'installation dure environ deux heures.

  • Une fois tout cela installé vous avez tout en main pour gérer les fonctions de traitement d'image. Cependant ce n'est pas terminé il fait maintenant utiliser sqlite3 pour gérer votre base de donnée.
  • Il suffit de rentrer la commande : sudo apt-get install sqlite3
  • Il vous reste à créer le fichier ".cpp" donner par le code ci dessous.

Pour compiler : g++ nom_du_fichier.cpp -lzbar -lopencv_highgui -lopencv_core -lopencv_imgproc -lsqlite3 nom_du_fichier_cible

  • Il ne vous reste plus qu'à tester. Petite précision : le programme ne fonctionne pas avec l'interface graphique fournit avec The Thing Box. Vous pouvez contrôler votre raspberry via un protocole ssh ou encore passer en mode "terminal uniquement" avec "ctr+alt+F5" et lancer le programme.

Code source

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <zbar.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h> 
#include <string.h>
using namespace cv;
using namespace std;
using namespace zbar;
static int callback(void *data, int argc, char **argv, char **azColName)
   {
   int i;
   fprintf(stderr, "%s", (const char*)data);
   for(i=0; i<argc; i++){
      printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }
   printf("\n");
   return 0;
}

int main(int argc, char *argv[])
{
	String res;
	char *res2;
    VideoCapture cap(0); // open the video camera no. 0
    cap.set(CV_CAP_PROP_FRAME_WIDTH,800);
    cap.set(CV_CAP_PROP_FRAME_HEIGHT,640);
   if (!cap.isOpened()) // if not success, exit program
   {
      cout << "Cannot open the video cam" << endl;
      return -1;
   }

   ImageScanner scanner;
   scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);

   double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video
   double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frames of the video
   bool flag;
   
   cout << "Frame size : " << dWidth << " x " << dHeight << endl;

   // namedWindow("MyVideo", CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"
 flag = true;
   while (flag==true) 
   {
      Mat frame;
      bool bSuccess = cap.read(frame); // read a new frame from video

      if (!bSuccess) //if not success, break loop
      {
         cout << "Cannot read a frame from video stream" << endl;
         break;
      }

      Mat grey;
      cvtColor(frame, grey, CV_BGR2GRAY);

      int width = frame.cols;
      int height = frame.rows;
      uchar *raw = (uchar *)grey.data;
      // wrap image data
      Image image(width, height, "Y800", raw, width * height);

      // scan the image for barcodes
      int n = scanner.scan(image);

      // extract results
      for(Image::SymbolIterator symbol = image.symbol_begin(); symbol != image.symbol_end(); ++symbol)
      {
         vector<Point> vp;
         res=symbol->get_data();
         // do something useful with results
        // cout << "decoded " << symbol->get_type_name() << " symbol \"" << res << "\"" << endl;

	int n = symbol->get_location_size();
        for(int i=0;i<n;i++)
        {
           vp.push_back(Point(symbol->get_location_x(i), symbol->get_location_y(i)));
        }

        RotatedRect r = minAreaRect(vp);
        Point2f pts[4];
        r.points(pts);

	res2=&res[0];

        for(int i=0;i<4;i++)
		{
          line(frame, pts[i], pts[(i+1)%4], Scalar(255,0,0), 3);
        }

    cout<<"Angle: "<<r.angle<<endl;
	flag = false;// get the correct data from the Qr code
     }

     
   }
    


   sqlite3 *db;
   char *zErrMsg = 0;
   int rc;
   char *sql;
   char *abo="SELECT nom, stock FROM temps WHERE id=";
   const char* data = "Callback function called";
   char *res3;
   strcpy(res3, abo);
   strcat(res3, res2);

   /* Open database */
   rc = sqlite3_open("mydatabase.db", &db);
   if( rc )
   {
      fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
      exit(0);
   }
       else
	   {
          fprintf(stderr, "Opened database successfully\n");
       }
   /* Create SQL statement */
   sql =res3;

   /* Execute SQL statement */
   rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
   if( rc != SQLITE_OK )
   {
      fprintf(stderr, "SQL error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
   }
   else
     {
        fprintf(stdout, "Operation done successfully\n");
     }
   sqlite3_close(db);

   return 0;
}

Différents étape du code

Étape 1 ouverture et enclenchement du module video
Dans cette étape on met en route la raspicam en mode vidéo cela se fait avec la commande "VideoCapture" et la commande "cap.set(CV_CAP_PROP_FRAME_WIDTH,800)" , "cap.set(CV_CAP_PROP_FRAME_HEIGHT,640)" pour régler la taille de l'image.

Étape 2 la Boucle
On fait une boucle pour pouvoir à la fois récupérer une image sur la vidéo et aussi décoder si c'est la cas le Qrcode et le stocker dans une variable ,la boucle s’arrête si on n'a réussit à décoder la première image (frame) contenant le Qrcode.

Étape 3 Base de donnée
On utilise des instructions en C++ pour pouvoir utiliser des requêtes SQl (base de donnée), ainsi nous allons réunir la donnée récupérée par le décodage qui contient un numéro unique dans la base de donnée codant un médicament unique, grâce à la requête SELECT en SQL permettant d'afficher des éléments qui sont dans la base de donnée comme la notice , le nom ... Nous avons mis une condition dans la requête SQL permettant d afficher les informations du médicament issu du décodage du Qrcode précédent (Where id=)

Cahier des charges

id nom notice notice avancée stock
1 dafalgan
Initialisation
  • Plug & Play
  • Autonomie
  • Dimension
Détection
  • Détection mouvement/présence = démarrage du système.
  • Tapis = Impact
  • Confirmation mouvement
  • Question/réponse => vocal
Mise en veille
  • Sortie de la salle de bain