Hajar Bouziane
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee
    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee
  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    RAPPORT TECHNHIQUE I. INTRODUCTION Dans le cadre de l'UE (Unité d'Enseignement) Internet des objets, il nous a été demandé de réaliser un système de surveillance d'examens. Il s'agit de créer une application qui communique avec un ordinateur selon le protocole client-serveur afin d'analyser le comportement d'un candidat pendant un examen. En effet, l'ordinateur qui joue le rôle de serveur doit pouvoir analyser les données envoyées par l'application qui simule le client afin de déterminer les suspicions de fraude que nous énumérons plus tard. Pour ce faire, l'application possède deux modes principaux. 1. Un mode tête qui signifie que l'application est placée sur la tête du candidat. Dans ce cas, elle va: - prendre une photo toutes les deux secondes pour les envoyer au serveur afin de lui montrer ce que le candidat voit pendant la réunion, - envoyer au serveur les coordonnées x y et z de l'accéléromètre placé dans l'appareil contenant l'application pour qu'il puisse déterminer les mouvements de la tête pendant la réunion. 2. Un mode main lorsque l'application est placée sur la main. Ainsi : - comme pour l'application, elle enverra au serveur les valeurs de l'accéléromètre, - elle affichera sur son écran un chronomètre montrant le temps écoulé depuis le début de la réunion. Ce projet a ainsi pour objectif de proposer un prototype d'outil d'aide à la prise de décision. Il retranscrit les suspiscions de fraude dans des fichiers Excel qui seront consultés par l'examinateur pour qu'il puisse en déduire s'il y a réellement eu au moins une fraude. Mais pour mieux comprendre la démarche entamée, nous avons rédigé ce rapport technique afin d'y décrire les fonctionnalités du système ainsi que les détails d'implémentation. II. gRPC : Remote Procedure Call gRPC est une technologie de communication open source développée par Google. Elle consiste en la création d'un service (avec ses méthodes, entrées et sorties) compatible avec de nombreux langages de programmation comme Java, Kotlin, Python, etc. Il permet ainsi de construire des liaisons client/serveur avec une très bonne prise en charge de la diffusion bidirectionnelle: * Le serveur implémente une interface et exécute un **serveur gRPC** pour gérer les clients, * Le client dispose d'un **stub** qui fournit les mêmes méthodes que le seveur pour qu'il puisse communiquer avec lui. C'est pour ces raisons que nous avons utilisé le protocole gRPC. Pour qu'il puisse effectuer des communications entre notre programme Kotlin (application mobile) et notre serveur Python (ordinateur portable). Voici une représentation simplifiée de notre protocole client-Serveur: ![](https://i.imgur.com/yIBHZOz.png) Pour mettre en place un tel protocole, il faut dans un premier temps créer un IDL (Interface Definition Language) qui n'est rien de plus qu'un contrat de service rédigé sous la forme d'un fichier texte `.proto`. Ainsi, grâce à ce dernier, le compilateur Protobuf `protoc` va pouvoir générer du code pour le client et le serveur. Dans le cas de notre système de surveillance d'examen, nous avons créé le fichier `envoie.proto` qui est composé : * de deux blocs identiques qu'on appelle des **messages** et qui sont composés d'une série de paires (type, nom de la variable) appelées **champs**. ```.proto // Bloc pour créer des messages message Envoie { // > Membres de la reunion string nomReunion = 1; string mailEtudiant = 2; // > Option string teteOuMain = 3; // > true pour reunion termine sinon false string etatReunion = 4; // > CameraX string image = 5; // > Accéléromètre float x = 6; float y = 7; float z = 8; // > Tentative de connexion string tentaConnec = 9; } ``` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=variable)%20appel%C3%A9es%20champs.-,//%20Bloc%20pour%20cr%C3%A9er%20des%20messages,-message%20Envoie%20%7B%0A%20%20%20%20//%20%3E%20Membres * d'un bloc qui définit le service gRPC et qui va être utilisé pour la communication client-serveur ```.proto // Bloc pour créer un service service EnvoieService { rpc GetEnvoie (GetEnvoieRequest) returns (Envoie); } ``` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=communication%20client%2Dserveur-,//%20Bloc%20pour%20cr%C3%A9er%20un%20service,-service%20EnvoieService%20%7B%0A%20%20%20%20rpc Dans un second temps, il faut mettre à jour le code gRPC (utilisé par notre serveur python) pour qu'il puisse utiliser notre service. Pour ce faire, on se place sur le répertoire où se trouve notre fichier proto (ici SpyCheat) et on exécute les commandes suivantes : ```python= # Installer python -m pip install --upgrade pip python -m pip install grpcio python -m pip install grpcio-tools # Générer les fichiers python -m grpc_tools.protoc -I../SpyCheat --python_out=. --grpc_python_out=. ../SpyCheat/envoie.proto ``` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=les%20commandes%20suivantes%20%3A-,%23%20Installer,-python%20%2Dm%20pip Les fichiers `envoie_pb2.py` et `envoie_pb2_grpc.py` sont alors générés et seront utilisés pour implémenter les fonctions de notre serveur pour qu'il puisse communiquer avec notre application. III. SpyCheat : Application android 1. Objectif L'application SpyCheat joue le rôle de client dans notre système de surveillance d'examens. Elle se découpe en 3 parties principales où la première sert à **créer** des réunions en donnant la liste des utilisateurs qui auront le droit d'y accéder. La seconde est utilisée pour lancer une réunion quand l'application est posée sur la **main**. Et pour finir, la troisième partie permet de participer à une réunion en ayant mis l'application sur la **tête**. Finalement, ces trois parties sont utilisées pour de détecter les tentatives de fraudes en s'assurant que uniquement les personnes inscrites peuvent se connecter à la réunion et en analysant des photos et les mouvements d'un candidat. 2. Prérequis Pour y parvenir, l'application à été crée sur Android Studio. Elle est composée de plusieurs fichiers dont : * `envoie.proto` : le même fichier que nous avons présenté dans la première partie et qui est stocké dans un répertoire nommé `proto` (lui même placé dans le répertoire `main`). * `build.gradle` : un fichier qui permet d'utiliser le compilateur protobuf (gRPC) et d'ajouter la caméra (caméraX) à notre code. Pour cela, il faut ajouter les lignes suivantes : * Dans le bloc des **plugins** : `id "com.google.protobuf" version "0.8.12"` `id 'distribution'` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=Dans%20le%20bloc%20des%20plugins * Dans le bloc **android** : `buildFeatures { viewBinding true }` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=Dans%20le%20bloc%20android * Dans le bloc des **dependences**: ``` //CAMERAX implementation "androidx.camera:camera-camera2:1.1.0-beta01" implementation "androidx.camera:camera-lifecycle:1.1.0-beta01" implementation "androidx.camera:camera-view:1.1.0-beta01" //GRPC implementation 'com.google.protobuf:protobuf-lite:3.0.1' implementation 'io.grpc:grpc-okhttp:1.25.0' // CURRENT_GRPC_VERSION implementation 'io.grpc:grpc-protobuf-lite:1.25.0' // CURRENT_GRPC_VERSION implementation 'io.grpc:grpc-stub:1.25.0' // implementation 'javax.annotation:javax.annotation-api:1.3.2 ``` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=Dans%20le%20bloc%20des%20dependences * Pour finir, on ajoute à la fin du fichier ce nouveau bloc: ``` protobuf { protoc { artifact = 'com.google.protobuf:protoc:3.10.0' } plugins { javalite { artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0" } grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.25.0' // CURRENT_GRPC_VERSION } } generateProtoTasks { all().each { task -> task.builtins{ remove java } task.plugins { javalite {} grpc { // Options added to --grpc_out option 'lite' } } } } } ``` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=bloc%20des%20dependences-,Pour%20finir%2C%20on%20ajoute%20%C3%A0%20la%20fin%20du%20fichier%20ce%20nouveau%20bloc%3A,-protobuf%20%7B%0A%20%20%20%20protoc%20%7B%20artifact * A cela s'ajoute un troisième et dernier fichier appelé `AndroidManifest.xml`. Il va servir à implémenter les permissions pour utiliser la caméra et la wifi : ``` <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-feature android:name="android.hardware.camera.any" /> <uses-permission android:name="android.permission.CAMERA" /> ``` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=xml.%20Il%20va%20servir%20%C3%A0%20impl%C3%A9menter%20les-,permissions%20pour%20utiliser%20la%20cam%C3%A9ra%20et%20la%20wifi,-%3A Une fois que c'est trois fichiers sont modifiés, il faut exécuter la commande `gradlew build` sur le terminal d'android studio pour que les fichiers contenant les fonctions gRPC soit générés. 3. Fonctionnement Une fois que la liste des prérequis ait été respéctée, nous pouvons nous intéresser aux fonctionnalités de l'application. En effet, cette dernière est composée de : * une page MainActivity.kt : l'utilisateur doit d'abord donner son authorisation pour que l'application puisse utiliser la caméra. Ensuite, il saisit l'adresse IP du réseau ainsi que le port pour que l'application puisse faire appel à la méthode suivante : ``` // Connexion au seveur val channel: ManagedChannel val newport = if (TextUtils.isEmpty(port)) 50051 else Integer.valueOf(port) channel = ManagedChannelBuilder .forAddress(host, newport) .usePlaintext() .build() ``` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=la%20m%C3%A9thode%20suivante%20%3A-,//%20Connexion%20au%20seveur,-val%20channel%3A%20ManagedChannel Si la connexion a échouée un message rouge s'affichera sur l'écran sinon l'utilisateur sera redirigé vers la page suivante. * une page d'accueil (AcceuilActivity.kt) : l'utilisateur à le choix entre créer une réunion ou se connecter à une réunion. * une page de création de réunion (InscriptionActivity.kt) : lorsque l'utilisateur arrive sur cette page, il doit remplir un formulaire en saisissant le nom d'une réunion et l'adresse mail d'un candidat. Pour valider l'inscription, il doit cliquer sur le bouton **envoyer**. La méthode suivante est alors exécutée pour que l'information soit envoyée au serveur : ``` // Si la connexion est un succès, on envoie nos données au serveur val stub: EnvoieServiceGrpc.EnvoieServiceBlockingStub = EnvoieServiceGrpc.newBlockingStub(channel).withDeadlineAfter(2,TimeUnit.SECONDS) val request: GetEnvoieRequest = GetEnvoieRequest.newBuilder() .setNomReunion(nomReu) //nom de la Réunion .setMailEtudiant(mailEtud) // mail de l'étudiant .setTeteOuMain(optionTeteOuMain) .setEtatReunion(etatReu) .setImage(imageForGRPC) .setX(x) .setY(y) .setZ(z) .setTentaConnec(tenteConnexion) //false car c'est un inscription et non une connexion .build() ``` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=envoy%C3%A9e%20au%20serveur%20%3A-,//%20Si%20la%20connexion%20est%20un%20succ%C3%A8s%2C%20on%20envoie%20nos%20donn%C3%A9es%20au%20serveur,-val%20stub%3A%20EnvoieServiceGrpc * une page de connexion (ConnexionActivity/kt) : le candidat doit saisir le nom de la réunion et son adresse mail. En cliquant sur le bouton **valider**, la méthode précédente est éxécutée en précisant cette fois qu'il y a une tentative de connexion (tenteConnexion = true). Si le candidat n'est pas inscrit, un message d'erreur s'affichera sinon il sera redirigé vers la page suivante. * une page OptionActivity.kt : le candidat a alors le choix entre deux options: * participer à la réunion en mode **tete**. Il sera alors redirigé vers la page de HeadActivity.kt et devra placer l'application sur sa tête. Lorsque la réunion débutera, la caméra se lancera ainsi que l'accéléromètre et leur données seront envoyées toutes les 2 secondes au serveur (toujours grâce à la méthode précédente). * participer à la réunion en mode **main**. Il sera donc redirigé vers la page HandActivity.kt et devra placer l'application sur sa main. Cette fois-ci c'est l'accéléromètre et le chronomètre qui sont lancé lorsque la réunion débutera. IV. Serveur : code python 1. Objectifs Placé sur un ordinateur portable, le serveur python se découpe en plusieurs parties. La première consiste à gérér les inscriptions et les connexions des utilisateurs. La seconde partie intervient lorsqu'une réunion a débuté en analysant les données (photos et accéléromètre) envoyées par l'application. Et pour finir, une troisième partie dédiée à l'enregistrement vocal. 2. Prérequis Pour lancer le serveur, il faut installer et importer un certain nombre de paquets : * Pour gRPC il faut importer : ```python= from concurrent import futures import logging import grpc import envoie_pb2 import envoie_pb2_grpc ``` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=nombre%20de%20paquets%20%3A-,Pour%20gRPC%20il%20faut%20importer,-%3A * Pour convertir en `.jpg` une image envoyée par l'application sous forme de chaîne de caractères : ```python= # Installer pip install base64 # Importer import base64 ``` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=faut%20importer%2C%2D%253A-,Pour%20convertir,-en%20.jpg%20une * Pour écrire et lire des fichiers CSV : ```python= # Installer pip install csv pip install os pip install pandas # Importer import csv import os import pandas as pd ``` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=en%20.jpg%20une-,Pour%20%C3%A9crire%20et%20lire%20des%20fichiers%20CSV,-%3A * Pour analyser les coordonnées de l'accéléromètre : ```python= # Installer pip install numpy # Importer import numpy as np ``` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=fichiers%20CSV%2C%2D%253A-,Pour%20analyser%20les%20coordonn%C3%A9es%20de%20l%E2%80%99acc%C3%A9l%C3%A9rom%C3%A8tre,-%3A * Pour l'enregistrement vocal il faut installer et importer : ```python= # Installer pip install sounddevice pip install wavio pip install wave # Importer import sounddevice as sd import wavio as wv import wave ``` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=de%20l%E2%80%99acc%C3%A9l%C3%A9rom%C3%A8tre%2C%2D%253A-,Pour%20l%E2%80%99enregistrement%20vocal,-il%20faut%20installer * Pour la reconnaissance de personne et d'objets sur les photos envoyé par l'application : ```python= # Installer pip install argparse pip install opencv-python pip install datetime # Importer import argparse import cv2 import datetime ``` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=de%20l%E2%80%99acc%C3%A9l%C3%A9rom%C3%A8tre%2C%2D%253A-,Pour%20l%E2%80%99enregistrement%20vocal%20il%20faut%20installer%20et%20importer,-%3A 3. Fonctionnement Une fois que la liste des prérequis ait été respecté, nous pouvons nous intéresser aux fonctionnalités du serveur. En effet, ce dernier est composé d'une fonction `server()` qui attend que des clients (maximum 10) se connectent sur son réseau. Dans ce cas là, il exécute la classe `Greeter()` à chaque fois que le client (application) lui envoie des données: ```python= # code server() def serve(): server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) envoie_pb2_grpc.add_EnvoieServiceServicer_to_server(Greeter(), server) server.add_insecure_port('[::]:50051') server.start() server.wait_for_termination() ``` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=envoie%20des%20donn%C3%A9es%3A-,%23%20code%20server(),-def%20serve()%3A%0A%20%20%20%20server Les données subissent alors une série de traitement que nous allons énumérer. Mais pour mieux comprendre les phases de traitement, nous allons nous baser sur des scénarios : * "*Je suis un utilisateur et je souhaiterai créer des réunions*". L'utilisateur est allé sur l'application SpyCheat et c'est dirigé vers la page des inscriptions. Lorsqu'il clique sur le bouton **"envoyer"** après avoir saisit le nom d'une réunion et l'adresse mail d'un candidat, le serveur va : * Si le fichier 'ReunionEtCandidats.csv' (stocke les réunions qui ont été créés) **n'existe pas**, le serveur le crée et écrit sur une ligne le nom de la réunion avec l'adresse mail du candidat inscrit à cette dernière * Si le fichier **existe** alors le serveur commence par vérifier si le candidat a déjà ou non été inscrit dans le fichier avec la fonction `def verifCandidat(reunion, mail)`. Dans le cas échéant, il est ajouté au fichier grâce à la fonction `def ajoutCandidat(reunion, mail)` sinon l'inscription est ignorée. * "*Je suis un candidat et je souhaiterai me connecter à une réunion*". Le candidat est allé sur l'application SpyCheat et c'est dirigé vers la page de connexion. Lorsqu'il a cliqué sur le bouton **"valider"** après avoir saisit le nom de sa réunion et son adresse mail, le serveur va : * Si les identifiants **ne sont pas inscrits** dans le fichier 'ReunionEtCandidats.csv' alors il envoie un message à l'application pour lui dire que le candidat ne peut pas se connecter à la réunion. Celle-ci reçoit l'information grâce à ces lignes de code : ```kotlin= // Réponse du serveur var reply : Envoie = stub.getEnvoie(request) // on veut savoir si le serveur a accépté ou refusé un demande de connexion if(reply.tentaConnec == "accepte"){ connectAuto = "accepte" } else if(reply.tentaConnec == "refuse"){ connectAuto = "refuse" } ``` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=lignes%20de%20code%20%3A-,//%20R%C3%A9ponse%20du%20serveur,-var%20reply%20%3A%20Envoie * Si les identifiants sont inscrits dans le fichier 'ReunionEtCandidats.csv' alors il envoie un message à l'application pour lui dire que le candidat a le droit de se connecter. Dans ce cas, il sera redirigé vers une page qui lui demandera de choisir entre l'option tête et l'option main. * "*Je suis un candidat est je souhaiterai participer à la réunion en mode tête (respectivement en mode main)*". Dans ce cas, le serveur ce doit de vérifier si le candidat a déjà participé à cette réunion ET avec ce mode. Pour ce faire, le serveur reçoit un message en provenance de l'application l'informant que ce candidat veut participer à cette réunion. Il parcourt alors un fichier appelé 'InventaireTeteReunionEtCandidats.csv' (respectivement 'InventaireMainReunionEtCandidats.csv') grâce à la fonction `def encours_ou_termine(fileName, reunion, mail, colonne, statut)` : s'il y est marqué que le candidat a déjà terminé la réunion, alors il envoie un message à l'application pour donner son désaccord. En revanche, si rien n'est indiqué dans le fichier, alors le serveur donne son accord à l'application et le candidat sera redirigé vers la page de réunion en mode tête. Notons que l'application reçoit la réponse du serveur grâce à ces lignes de code : ```kotlin= var reply : Envoie = stub.getEnvoie(request) if(reply.tentaConnec == "accepte"){ connectAuto = "accepte" } else if(reply.tentaConnec == "refuse"){ connectAuto = "refuse" } // c'est cette condition qui entre en jeu ! else if (reply.tentaConnec == "fini"){ tenteConnexion = "fini" } ``` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=lignes%20de%20code%20%3A-,var%20reply,-%3A%20Envoie%20%3D%20stub.getEnvoie * "*Je suis un candidat et je participe à la réunion en mode main*". Lorsque le candidat clique sur le bouton **"commencer"**, plusieurs évènements entrent en jeu : * Premièrement, le serveur écrit dans le fichier 'InventaireTeteReunionEtCandidats.csv' que la réunion est en cours grâce à la fonction `def inventaire(fileName, reunion, mail, colonne, etatReu)`. Ce même fichier est mis à jour lorsque le candiat quitte la réunion en écrivant "terminé". * Deuxièmement, il lance l'enregistrement vocal grâce à la fonction `def record()`. Cette dernière lance un enregistrement toutes les 5 secondes et les concatènent au fur et à mesure pour ne former qu'un seul audio. Notons que l'enregistrement se termine lorsque le candidat a quitté la réunion. * Troisièment, il traite les valeurs de l'accéléromètre grâce à la fonction `def calibrage(x, y ,z ,nb_ite)`. Cette dernière commence par faire une moyenne des 5 premières coordonnées envoyées par l'application. Ainsi si les nouveaux coordonnées s'éloigne de la moyenne (à partir d'un certains seuil), le serveur est en mesure de déterminer s'il y a eu un mouvement droite, gauche, haut ou bas de la tête. * Quatrièmement, il traite les images envoyées par l'application. Pour ce faire, grâce à la fonction `def base64_to_image (img_data)` la chaine de caractère est d'abord converti en image `.jpg`. Puis, un algorithme est alors appliqué à cette image de façon a reconnaître les objets et les personnes présent sur la photo et les écrits dans le fichier `Objects_Detection.csv`. * "*Je suis un candidat et je participe à la réunion en mode main*". Lorsque le candidat clique sur le bouton **"commencer"**, seules les valeurs de l'accéléromètre sont envoyées au serveur. Mais par manque de temps, ces dernières ne sont pas traitées. V. Reconnaissance Faciale : script python 1. Objectif Le but était d'implémenter une solution de reconnaissance faciale au niveau de la webcam de l'ordinateur. Cette dernière devait être capable de reconnaître la personne qui passait l'examen et d'enregistrer en cas de suspicion de fraude. 2. Prérequis Il faut installer toutes les librairies suivantes dans votre environnement python pour permettre à l'utilisateur de lancer les scripts : https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=suspicion%20de%20fraude.-,Pr%C3%A9requis,-Comment ```python= # Installer pip install opencv-python pip install dlib pip install numpy pip install imutils pip install pillow # Importer import cv2 import dlib import PIL.Image import numpy as np from imutils import face_utils import argparse from pathlib import Path import os import ntpath import datetime import glob import time from imutils.video import FPS ``` 3. Fonctionnement Une fois que nous avons les prérequis nécessaire nous pouvons lancer le script python pour nous prendre en photo avant l'examen : ```python= #Une fois que nous sommes dans le répertoire easy_facial_recognition-master, nous lançons sur le terminal ceci : python 01_face_dataset.py ``` https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=%23-,Une%20fois%20que%20nous%20sommes%20dans%20le%20r%C3%A9pertoire,-easy_facial_recognition%2Dmaster%2C%20nous%20lan%C3%A7ons%20sur%20le%20terminal%20ceci%20%3A%20%0Apython Il faudra ensuite écrire votre nom puis appuyer sur entrée pour que la photo soit prise et enregistrée dans le dossier known_faces. Ensuite, nous pouvons d'ores et déjà lancer la commande qui va nous permettre de lancer la webcam de l'ordinateur pour faire l'examen. La commande est la suivante : https://hackmd.io/S18oxuh6Tc6fCS1Hrfc1ZA?both#:~:text=pour%20faire%20l%E2%80%99examen.-,La%20commande%20est%20la%20suivante,-%3A ```python= python easy_facial_recognition.py --i known_faces ``` Des informations sont communiquées sur le terminal pour voir l'avancé du chargement. Un message sera affiché pour pouvoir entrer le nom de la personne qui passera l'examen. Voici les différents scénarios que nous avons traité : Si la personne n'entre pas le bon nom, elle se verra être enregistrée puis on stockera la personne que nous verrons dans un fichier qui se nommera comme le nom qu'elle a entré pour se connecter. Si la personne entre le bon nom puis au cours de l'examen se lève pour aller ailleurs, un enregistrement sera pris (dans le dossier recording) et pourra servir de preuve. De plus sur le fichier csv (dans le dossier Students puis dans le dossier de l'élève en question ) généré à son nom il y aura un intervalle de temps où la personne ne saura pas notée (nom de la personne et la date(jour,heure,seconde)). Si la personne entre le bon nom puis au cours de l'examen un autre élève entre dans le champs de vision de la webcam, un enregistrement sera pris (dans le dossier recording) et pourra servir de preuve. De plus sur le fichier csv (Attendance.csv) généré il y aura écrit soit le nom de la seconde personne si l'algorithme le reconnait soit comme étant un inconnu (nom de la personne et la date(jour,heure,seconde)). ==================================================================== ==================================================================== Ce que j'ai fais : | Date | Description des tâches | | ----------- | ---------------------- | | 16/12/2021 | Prise en main de gRPC avec le TP1 : <br> - lecture du quickstart sur le langage Python <br> - installation de jdk 11 <br> - installation de gRPC sur Windows <br> - test et compréhension du code fournis par quickstart | | 06/01/2022 | Lecture et compréhension des fichiers stockés sur Google Colab (TP2) | | 11/01/2022 | Avec Sohayla RABHI on a réfléchi aux fonctionnalités qui allaient être présentes dans notre application à savoir : <br> - une page d'accueil où on doit saisir ses identifiants et choisir entre créer ou rejoindre une réunion, <br> - Une seconde page pour lancer la réunion où il y aura la caméra, le chronomètre et un bouton pour quitter la réunion. <br> Puis on a créé une maquette de l'application SpyCheat sur ce [site](https://www.figma.com/file/31tmeAVBcng0u39nZ2XBNx/SpyCheat?node-id=2%3A6). Par la suite, nous nous sommes réparties les tâches (pour ma part, je devais m'occuper de la connexion gRPC ). |18/01/2022| Avec Sohayla RABHI à commencer pas prendre en main Android Studio en débutant par créer notre application : on a créé une page qui sert à lancer le chronomètre (interface xml et code kotlin) | | 19/01/2022 | Prise en main gRPC avec python : <br> - J'ai testé le code HelloWorld et RouteGuide en python pour comprendre le code. <br> - J'ai effectué des test en mettant en commentaires des fonctions et en modifiant des valeurs pour qu'elle s'adapte à mes besoins.<br> - J'ai fait des recherches sur internet pour comprendre le rôle du fichier proto | | 20/01/2022 | J'ai ajouté l'accéléromètre à l'application et j'ai regardé à quoi correspondait les valeurs.| | 26/01/2022 | - J'ai créé un fichier proto pour que celui-ci récupère juste les valeurs de l'accéléromètre. <br> - J'ai créé un serveur python pour que celui-ci affiche les valeurs envoyées par un client. <br> - Création d'un client python pour que celui-ci envoie 3 valeurs (comme ci c'était des coordonnées). L'objectif était de tester le bon fonctionnement de mon serveur et comprendre le rôle des fonctions gRPC.| | 28/01/2022 | - Nouvelle tentative de création d'un serveur et d'un client python qui fut un succès. <br> - Première tentative de création d'un client kotlin sur android studio (échec). J'ai rencontré de nombreuse difficulté pour générer les bons fichiers gRPC. Il m'a fallut regarder plusieurs fois le code qui était mis à notre disposition dans le quickstart.| | 29/01/2022| Seconde tentative de création création d'un client kotlin (échec) | | 30/01/2022| Troisième tentative de création d'un client kotlin (échec) | | 31/01/2022| Quatrième tentative de création d'un client kotlin : Succès. Le serveur reçoit les coordonnées de l'accéléromètre même lorsqu'on débranche le câble de l'application. J'ai donc pu créer la page d'acceuil de l'application. J'ai ajouté sur la même page que le chronomètre l'accéléromètre pour tester les latences (il n'y en avait pas) | | 03/02/2022 | J'ai montré à mes caramades comment faire fonctionner gRPC sur android studio (de la création du client en kotlin au serveur python) | | Du 10/02/2022 au 16/02/2022 | J'ai fusionné le code de sohayla qui servait à faire la reconnaissance faciale sur l'application Android Studio. Cependant, il y avait de trop grande latence et l'application cessait de fonctionner. De plus, il était impossible de lancer la reconnaissance faciale en même temps que l'accéléromètre malgré le fait que j'ai ajouté des thread et/ou diminiuer augmenter le temps d'anvoie des données au serveur. J'ai donc décidé d'envoyer les images au serveur via gRPC | | 17/02/2022 | - J'ai ajouté la caméra sur l'application et sur le fichier proto (j'ai fais des recherches pour trouver les bonnes permissions) <br> - J'ai ajouté des fonctions kotlin pour convertir les images (en format bitmap) en chaîne de caractères avant qu'elles soient envoyées au serveur <br> - J'ai modifié le serveur pour qu'il puisse convertir les chaînes de caractères en image <br> - J'ai rédigé des scénarios et j'ai redéfinis la maquette de l'application pour qu'elle réponde à nos attentes (j'ai fais des schémas en spécifiants les différentes conditions à respecter).| | Du 19/02/2022 au 25/02/2022 | J'ai modifié le fichier proto pour qu'il puisse créer des messages contenant les images, les valeurs de l'accéléromètre, les tentatives de connexion sur la main et la tête, le nom des réunions et les adresses mails des utilisateurs. Par la suite, j'ai créé un nouveau projet pour l'application avec toutes les pages qui ont été énumérées dans le cahier des charges techniques. J'ai modifié le serveur pour qu'il crée des fichiers CSV, qu'il gère les créations de réunion et les tentatives de connexion, qu'il lance et arrête l'enregistrement vocal au bon moment (qu'il respecte le cahier des charges). | | 26/02/2022 | Fusion de mon serveur python avec les codes de Sohayla. On a corrigé quelques bugs et on a fait des tests qui ont tous fonctionnés. | | 27/02/2022 | Avec Sohayla on a créé les vidéos et les slides pour la présentation du lendemain.| ==================================================================== ==================================================================== Sohayla Ce que j'ai fais : | Date | Description des tâches | | ----------- | ---------------------- | | 16/12/2021 | Prise en main de gRPC avec le TP1 : <br> - lecture du quickstart sur le langage Python <br> - installation de jdk 11 <br> - installation de gRPC sur Windows <br> - test et compréhension du code fournis par quickstart | | 06/01/2022 | Lecture et compréhension des fichiers stockés sur Google Colab (TP2) | | 11/01/2022 | Avec Sohayla RABHI on a réfléchi aux fonctionnalités qui allaient être présentes dans notre application à savoir : <br> - une page d'accueil où on doit saisir ses identifiants et choisir entre créer ou rejoindre une réunion, <br> - Une seconde page pour lancer la réunion où il y aura la caméra, le chronomètre et un bouton pour quitter la réunion. <br> Puis on a créé une maquette de l'application SpyCheat sur ce [site](https://www.figma.com/file/31tmeAVBcng0u39nZ2XBNx/SpyCheat?node-id=2%3A6). Par la suite, nous nous sommes réparties les tâches (pour ma part, je devais m'occuper de la reconnaissance faciale ). |18/01/2022| Avec Hajar BOUZIANE on a commencé par prendre en main Android Studio en débutant par créer notre application : on a créé une page qui sert à lancer le chronomètre (interface xml et code kotlin) | | 19/01/2022 | Ajout de la caméra sur l'application | | 20/01/2022 | Test et débogage de différents codes qui faisaient la reconnaissance faciale sur Android studio | | 26/01/2022 | Test et débogage de différents codes qui faisaient la reconnaissance faciale sur Android studio | | 28/01/2022 | Débogage | | 29/01/2022| Débogage | | 30/01/2022| Débogage | | 31/01/2022| Ecriture d'un nouveau code de reconnaissance faciale via un tutoriel vidéo | | 03/02/2022 | Ecriture d'un nouveau code de reconnaissance faciale via un tutoriel vidéo, le code semble fonctionner sans problème | | Du 10/02/2022 au 16/02/2022 | J'améliore le code de la reconnaissance faciale sur l'application et puis je le donne à Hajar BOUZIANE pour la fusion de nos partie. Après ça, je commence à rechercher des algorithmes de reconnaissance faciale pour la webcam de l'ordinateur | | 17/02/2022 | J'ai créé une interface python où je pouvais apercevoir ce que la webcam voyait grâce à un tutoriel mais il y avait beaucoup trop de latence donc j'ai commencé à rechercher d'autres algorithmes. | | Du 19/02/2022 au 22/02/2022 | Avec tous les algorithmes que j'ai trouvé j'ai pris les bouts de code que j'ai trouvé intéressant pour notre reconnaissance faciale. : - J'ai trouvé un nouveau tutoriel qui me permet de prendre en photo la personne avant l'examen. - Un qui permet de reconnaitre la personne devant la webcam (avec moins de latence que l'ancien, mais il y en a un peu tout de même). -Un autre qui permet d'enregistrer dans un fichier csv ce qu'on observe (code qui a servi pour l'application et la webcam). | | Du 23/02/2022 au 25/02/2022 | Je définis les scénarios qui peuvent être considérés comme de la triche et je les implémente dans le code. Ensuite, je crée une reconnaissance d'objets et de personne dans le serveur d'Hajar pour analyser les images qu'elle envoie au serveur depuis l'application. | | 26/02/2022 | Fusion de mon serveur python avec les codes de Hajar. On a corrigé quelques bugs et on a fait des tests qui ont tous fonctionnés. | | 27/02/2022 | Avec Hajar on a créé les vidéos et les slides pour la présentation du lendemain.|

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully