Académique Documents
Professionnel Documents
Culture Documents
Réalisé par :
- MIKOU Badr.
- ANNAKI Hajar.
- BAGUENNA Oussama.
- OURINAH Badr.
Encadré par :
- Mr. RAQEN Fouad.
Ingénieur Systèmes Embarqués chez
ALTEN DC Maroc
Remerciement
Ce travail, ainsi accompli, n’aurait point pu arriver à terme, sans l’aide et le soutien et tout le
guidage d’ALLAH, louange au Seigneur de l’univers.
En second lieu nous tenons à remercier nos parents pour leur assistance morale infiniment
soutenant.
On remercie particulièrement :
Notre encadrant Monsieur RAQEN Fouad pour son aide, son soutien et ses consignes tout au
long de l’achèvement de ce stage de fin d’année.
Tout le corps professoral et administratif de nos écoles supérieur respectives pour leur soutien.
Enfin, on veut rendre hommage à toutes les personnes qui n’ont pas hésité à nous aider d’une
manière ou d’une autre durant notre étude.
Dédicaces
Avec l’expression de ma reconnaissance, je dédie ce travail à ceux à qui, quels que soient les
termes embrassés, je n’arriverais jamais à exprimer mon amour sincère :
• À l’homme, ma précieuse offre du dieu, à qui je dois ma vie, ma réussite et tout mon
respect : mon cher père.
• À la femme qui a souffert sans me laisser souffrir, qui n’a jamais dit non à mes exigences
et qui n’a épargné aucun effort pour me rendre heureux : ma mère.
• À mon très cher frère, qui n’a pas cessé de m’encourager.
• À mon encadrant Mr. RAQEN Fouad, qui n’a pas cessé de m’encourager et de me
soutenir durant toute la durée du stage.
• À tous les cousin(e)s, les voisin(e)s et les ami(e)s que j’ai connu jusqu'à maintenant.
Merci pour leurs encouragements.
Sans oublier mes collègues et toutes personnes qui ont contribué de près ou de loin par leur
soutien moral tout au long de ce projet.
MIKOU Badr
Dédicaces
Je dédie ce travail à :
➢ Mes parents :
Chère mère et cher père je vous remercie beaucoup pour tous les sacrifices que vous avez fait
pour moi, et qui ont fait de moi la personne que je suis aujourd’hui.
A ce moment mémorable pour moi ainsi que pour vous, je vous présente ce travail comme fruit
de vos sacrifices.
➢ Mes collègues
A mes collègues pour leur soutien, patience et leur compréhension tout au long de ce travail.
➢ Mes Professeurs
Il vous revient le mérite de nous avoir prodigué un enseignement profitable et une formation
complète.
➢ Mon Encadrant
Sans oublier mon encadrant qui nous accompagné, soutenu et encouragé à accomplir ce projet.
ANNAKI Hajar
Dédicaces
Je dédie ce travail :
A mes chers parents qui ne cessent de nous encourager à aller de l’avant pour assurer
davantage notre avenir ;
A mes chers professeurs pour la formation, le suivi et les précieux conseils dont nous avons
bénéficié tout au long de notre parcours d’études ;
A notre encadrant Mr DIOURI Mohammed, professeur (FSI UPF) qui nous a aidé beaucoup
pour la réalisation de ce travail ;
A Mr RAQEN FOUAD, Ingénieur en ALTEN pour leur effort, soutien, encouragement, temps
accordé, explication… tout au long de notre durée de stage ainsi que tous les membres de
l’entreprise ALTEN
BAGUENNA Oussama
Dédicaces
Je dédie ce mémoire à :
Ma mère que nulle dédicace ne puisse exprimer mes sincères sentiments envers elle, pour son
encouragement, son aide, sa patience illimitée en témoignage de mon profond amour et respect
pour ses sacrifices.
Ma sœur : Hajar pour son grand amour et son soutien qu’il trouve ici l’expression de ma haute
gratitude.
OURINAH Badr
Résumé
L'identification des panneaux routiers dans les images est un problème important, en
particulier pour les applications de sécurité des véhicules et de gestion des routes. Elle est
généralement abordée en deux étapes : détection, reconnaissance et parfois on ajoute le suivi,
et évaluée dans son ensemble. Pour progresser vers de meilleurs algorithmes.
Dans le cadre de ce stage de fin d’année, chez ALTEN Delivery Center, on s’intéresse à la
reconnaissance des panneaux de limitations de vitesses en utilisant des modèles basés sur
l’architecture des réseaux de neurones convolutifs (convolutional neural networks ou CNN).
Abstract
Identifying road signs in images is an important issue, especially for vehicle safety and road
management applications. It is usually approached in two stages: detection, recognition and
sometimes we add tracking, and evaluated as a whole. To progress towards better algorithms.
As part of this end-of-year internship, at ALTEN Delivery Center, we are interested in the
recognition of speed limit panels using models based on the architecture of convolutional
neural networks (CNN).
The realization of this project takes place in two stages: Firstly, the recognition of the speed
limit panels using convolutional neural networks and secondly to vary the speed of a DC motor
by deploying the models on an embedded card (the Raspberry pi in our case) using the
interfacing between the embedded card and the MATLAB software.
Sommaire
REMERCIEMENT ...................................................................................................................I
DEDICACES ........................................................................................................................... II
DEDICACES .......................................................................................................................... IV
DEDICACES ........................................................................................................................... V
RESUME ................................................................................................................................. VI
SOMMAIRE ........................................................................................................................VIII
INTRODUCTION : ...................................................................................................................... 2
I. PRESENTATION DE L’ENTREPRISE D’ACCUEIL : ................................................................ 2
1. Quelle est la société ALTEN :.................................................................................... 2
2. ALTEN Maroc : ......................................................................................................... 2
II. DESCRIPTION DU PROJET REALISE : .................................................................................. 6
III. CONTEXTE MATERIEL DU PROJET : .............................................................................. 6
1. La carte Raspberry PI : ............................................................................................... 6
2. La caméra du Raspberry Pi : ...................................................................................... 8
3. Module L298N : ....................................................................................................... 10
4. Moteur à courant continue : ..................................................................................... 11
IV. CONTEXTE LOGICIEL DU PROJET : .............................................................................. 11
1. Anaconda : ................................................................................................................ 11
2. Matlab : .................................................................................................................... 17
CONCLUSION : ....................................................................................................................... 20
INTRODUCTION : .................................................................................................................... 21
I. ARCHITECTURE D’UN RESEAU CNN : ............................................................................ 21
1. La couche de convolution : ...................................................................................... 22
2. Couche de mise en commun : .................................................................................. 25
3. Couche entièrement connectée : ............................................................................... 26
CONCLUSION : ....................................................................................................................... 28
INTRODUCTION : .................................................................................................................... 29
I. LA CREATION DES MODELES : ........................................................................................ 30
1. Le prétraitement des données : ................................................................................. 30
2. La création des modèles : ......................................................................................... 33
II. LA GENERATION DU CODE C++ ET LE DEPLOIEMENT DU CODE MATLAB VERS LA CARTE
RASPBERRY PI : ..................................................................................................................... 40
CONCLUSION : ....................................................................................................................... 43
INDEX ..................................................................................................................................... 45
Introduction générale
L'année 1981 est devenue le point de pivot de l'industrie automobile mondiale lorsque les
ingénieurs des constructeurs automobiles ont installé la première unité de commande du moteur
(ECU) dans un véhicule. En 1998, ce constructeur automobile a lancé le logiciel BMW Assist
Service fonctionnant sur l'ordinateur embarqué dans un véhicule. Néanmoins, les voitures
équipées de ce service d'assistance étaient plus intelligentes que les utilisateurs ne pouvaient
l'imaginer et sont devenues la base des applications d'IA sur lesquelles travaille l'industrie
aujourd'hui.
Les assistants de conduite basés sur l'IA apportent des changements massifs aux mesures de
navigation et de sécurité sur la route. Non seulement ils facilitent la conduite pour les personnes
inexpérimentées, mais ils améliorent également la communication entre la voiture et son
propriétaire en les reliant.
Ce stage de fin d’année s’inscrit dans le secteur d’automobile et précisément dans l’équipe des
systèmes embarqués.
Ce projet de stage de fin d’année a pour objectif de développer un système capable de détecter,
voir reconnaître les panneaux de limitation de vitesse sur une photo. Les applications de ce
projet sont multiples : en équipant les voitures de caméra et de ce système, on sera en mesure
non seulement de proposer une aide au conducteur, mais on pourrait aussi envisager une
régulation automatique de la vitesse du moteur de voiture, qui aurait donc besoin de connaître
les vitesses particulières aux endroits dans lesquels il roule, et donc de détecter et reconnaître
les panneaux.
Introduction :
Avant d’exposer notre travail, prenant pour occasion de présenter la société d’accueil, son
historique, ses domaines d’activités afin de mieux situer le sujet de notre travail lors de cette
durée de stage. Ainsi de présenter le sujet du stage, ses objectifs, est son contexte matériel et
logiciel.
Le Groupe est présent dans le monde dans 30 pays notamment en Allemagne, en Autriche, en
Italie, ainsi qu’au Maroc, Elle accompagne la stratégie de développement de ses clients dans
les domaines de l’innovation, de la Recherche et Développement et des systèmes d’information
technologiques. Toute l’équipe ALTEN vise à réaliser des projets de conception et d’études
pour les directions techniques et les directions des Systèmes d’informations des secteurs du
transport terrestre (Automobile/Ferroviaire), de l’aéronautique, de l’énergie, des
télécommunications, et de la finance.
ALTEN propose à ses clients la mise à disposition d'ingénieurs intervenant sur leurs projets
technologiques en mode régie allant de la journée à plusieurs années.
2. ALTEN Maroc :
a. Aperçu général :
Filiale Marocaine à 100% du Groupe ALTEN, ALTEN Maroc, avec ses 700 ingénieurs, permet
à ce dernier de répondre aux besoins du marché marocain en termes d’expertise technique et de
faire bénéficier ses clients internationaux d’une plateforme Nearshore performante.
Avec le Centre de Delivery situé au Fès Shore, ainsi que le nouveau Site situé à Technopolis
Rabat, la filiale marocaine, ALTEN Delivery Center Maroc, a pour vocation de déployer une
stratégie globale permettant à ses clients de bénéficier d'une prestation de qualité mais aussi de
proximité à un coût très compétitif.
ALTEN Maroc Poursuit sa croissance et inaugure son nouveau centre en 2020 à Casa
Nearshore.
ALTEN intervient auprès des grands acteurs des secteurs Aéronautique & Spatial, Défense &
Naval, Sécurité, Automobile, Ferroviaire, Energie, Sciences de la vie, Finance, Retail,
Télécommunications et Services.
L'industrie automobile marocaine a enregistré une croissance remarquable au cours des dix
dernières années. Une progression fulgurante qui n'est pas près de s'arrêter. Ainsi, le Maroc est
devenu le deuxième producteur de véhicules en Afrique après l’Afrique du Sud, avec une part
de marché de 35% en 2014 contre 5% en 2003.
Près de 36.500 emplois ont été créés dans le secteur entre 2009 et 2014, soit un accroissement
annuel moyen de 12,4%. Et avec 39,8 milliards de dirhams (+/- 3,7 milliards d’euros) de chiffre
d’affaires à l’export réalisés en 2014, contre 31 milliards de dirhams (+/- 2,9 milliards d’euros)
en 2013, l’automobile se positionne au 1er rang des secteurs exportateurs.
d. L’Organisation de l’entreprise :
L’entreprise ALTEN est divisée en 3 départements qui sont représentés comme suit :
Management du projet : Constitué des managers et des directeurs de projet qui sont
responsables de l’aboutissement des projets sur le plan du budget ou du coût, sur le plan des
délais (des plannings, des jalons), sur le plan du respect des spécifications et sur le plan de la
qualité.
❖ Support : constitué de :
Ce système peut être lié à un système de régulation de vitesse, ce dernier permet de réguler la
vitesse du moteur à fin que le conducteur puisse respecter le code de conduite d’une manière
plus efficace est dans les pires cas possibles.
Notre projet intitulé « la régulation de la vitesse d’une voiture selon les panneaux de
limitations » permet d’adapter la vitesse d’un moteur à courant continu DC en lisant la vitesse
sur les panneaux de vitesses.
• La partie Intelligence Artificielle : cette partie a pour objectif la création d’un modèle
de reconnaissance des panneaux de limitation de vitesses. Dans cette partie on a créé deux
modèles de réseau de neurone, un modèle nous informe si un panneau est un panneau de
limitation de vitesse ou non, et un deuxième 2ème qui classifie le panneau dans la bonne
catégorie des vitesses.
incroyables, mais pour mettre en ligne des projets à montrer au client ou expérimenter avec
Linux, c'est largement suffisant.
Il est important de noter qu'il existe de multiples variantes de ce nano ordinateur. En effet,
beaucoup de personnes ont décidé de faire des forks du Raspberry pi en proposant des
configurations différentes suivant les besoins. Dans ce projet on s’intéresse à la carte Raspberry
pi 3 B+.
a. Le fonctionnement :
Avant de nous lancer dans des cas d'utilisation il est important de comprendre comment
fonctionne un Raspberry pi. La Raspberry pi ne dispose pas d'un disque dur interne (cela
augmenterait grandement sa taille) et on stockera les données sur une carte SD. Par défaut, la
Raspberry pi, est nu, comprendre par là qu'il est vendu sans accessoires. Pour pouvoir l'utiliser
vous devrez donc avoir
• Une carte micro SD compatible avec le modèle Raspberry pi que vous avez choisi.
• Un câble d'alimentation micro USB standard.
• Un câble RJ45 pour se connecter au réseau.
• Un câble HDMI afin de connecter la Raspberry pi un écran ou une télévision.
• Un clavier pour taper les commandes.
Pour travailler avec la Raspberry il faut d’abord faire quelque configuration est suivre les étapes
suivantes :
• Une fois la carte micro SD préparée, il suffit de l'insérer dans votre Raspberry pi pour
faire fonctionner automatiquement le système. Suivant la distribution que vous avez
choisie vous devriez tomber sur l'écran de configuration de la Raspberry pi (vous
pourrez accéder à cet écran plus tard en tapant la commande sudo raspi-config) afin de
configure la Raspberry selon le besoin.
• Avant de vouloir aller plus loin il est important de donner à notre Raspberry pi une IP
fixe afin de pouvoir s'y connecter facilement depuis le réseau local. En effet, par défaut
la Raspberry pi va changer d'IP à chaque connexion ce qui peut rapidement s'avérer
pénible
2. La caméra du Raspberry Pi :
’est un module miniature avec une définition de 5 Mégapixels et 1080p en vidéo. La caméra se
branche sur le connecteur CSI existant sur la carte Raspberry Pi. Elle convient pour Raspberry
Pi modèle A ou B.
a. Caractéristique :
• Capteur Omnivision 5647 avec objectif à focale fixe
• Capteur 5 Mégapixels
• Résolution photo : 2592 x 1944
• Résolution vidéo maximum : 1080p
• Images par seconde maximum : 30fps
• Taille du module : 20 x 25 x 10mm
• Connexion par câble plat à l’interface 15-pin MIPI Camera Serial Interface (CSI)
(Connecteur S5 du Raspberry Pi)
3. Module L298N :
Ce breakout board est un Double Pont-H destiné au contrôle de moteur continu (H-Bridge
Motor Driver). Il est basé sur le composant L298N qui est un double Pont-H conçu
spécifiquement pour ce cas d'utilisation. C'est un module extrêmement utile pour le contrôler
de robots et ensembles mécanisés. Il peut contrôler deux moteur courant continu ou un moteur
pas-à-pas 4 fils 2 phases. Il est conçu pour supporter des tensions plus élevées, des courants
importants tout en proposant une commande logique TTL (basse tension, courant faibles, idéal
donc pour un microcontrôleur). Il peut piloter des charges inductives comme des relais,
solénoïdes, moteurs continus et moteurs pas-à-pas. Les deux types de moteurs peuvent être
contrôlés aussi bien en vitesse (PWM) qu'en direction. Toutes les sorties en puissance sont déjà
protégées par des diodes anti-retours. Il s'agit d'un module prêt à l'emploi.
a. Spécifications :
• Composant de contrôle en puissance : L298N.
• Alimentation de la charge : de +6V à +35V.
• Courant Max (en pointe) : 2A.
• Tension de commande logique Vss : de +5 à +7V (alimentation interne de +5V).
• Courant de commande logique : de 0 à 36mA.
• Tensions pour contrôle du sens : Low -0.3V~1.5V, high : 2.3V~Vss.
• Tensions pour contrôle « Enable » : Low -0.3V~1.5V, high : 2.3V~Vss.
• Puissance Max : 25W (Température 75 °C).
• Température de fonctionnement : de -25°C à +130°C.
• Dimensions : 60mm x 54mm.
• Poids : ~48g.
b. Idées d’application :
• Pilotage de moteur continu (eg : voiture téléguidée, montage divers à base de moteurs).
• Pilotage de moteur pas-à-pas 4-fils deux-phase.
Un moteur à courant continu est constitué de deux parties électriques : le stator et le rotor.
Lorsqu'on alimente le moteur, il se crée une interaction magnétique qui met le moteur en
mouvement. Lorsqu'on inverse le sens de la tension qui alimente le moteur, il tourne en sens
inverse.
scientifique), qui vise à simplifier la gestion des paquets et de déploiement. Les versions de
paquetages sont gérées par le système de gestion de paquets conda. La distribution Anaconda
est utilisée par plus de 6 millions d'utilisateurs et comprend plus de 250 paquets populaires en
science des données adaptés pour Windows, Linux et MacOS.
Le Navigateur Anaconda est une interface graphique (GUI) incluse dans la distribution
Anaconda, et qui permet aux utilisateurs de lancer des applications, mais aussi de gérer les
librairies conda, les environnements et les canaux sans utiliser la moindre ligne de commande.
Le Navigateur peut également accéder à des librairies présentes sur le Cloud Anaconda ou dans
un Repository Anaconda local, afin de les installer dans un environnement, les exécuter et les
mettre à jour. Il est disponible pour Windows, macOS et Linux. Les applications suivantes sont
disponibles par défaut dans le navigateur :
• JupyterLab.
• Jupyter Notebook.
• QtConsole5.
• Spyder.
• Glue.
• Orange.
• RStudio.
• Visual Studio Code.
a. Python :
Python est un langage de programmation interprété, multiparadigme et multiplateformes. Il
favorise la programmation impérative structurée, fonctionnelle et orientée objet. Il est doté d'un
typage dynamique fort, d'une gestion automatique de la mémoire par ramasse-miettes et d'un
système de gestion d'exceptions ; il est ainsi similaire à Perl, Ruby, Scheme, Smalltalk et Tcl.
Le langage Python est placé sous une licence libre proche de la licence BSD et fonctionne sur
la plupart des plates-formes informatiques, des smartphones aux ordinateurs centraux, de
Windows à Unix avec notamment GNU/Linux en passant par macOS, ou encore Android, iOS,
et peut aussi être traduit en Java ou .NET. Il est conçu pour optimiser la productivité des
programmeurs en offrant des outils de haut niveau et une syntaxe simple à utiliser. Il est
également apprécié par certains pédagogues qui y trouvent un langage où la syntaxe, clairement
séparée des mécanismes de bas niveau, permet une initiation aisée aux concepts de base de la
programmation. Python est un langage de programmation qui peut s'utiliser dans de nombreux
contextes et s'adapter à tout type d'utilisation grâce à des bibliothèques spécialisées. Il est
cependant particulièrement utilisé comme langage de script pour automatiser des tâches simples
mais fastidieuses, comme un script qui récupérerait la météo sur Internet ou qui s'intégrerait
dans un logiciel de conception assistée par ordinateur afin d'automatiser certains enchaînements
d'actions répétitives (voir la section Adoption). On l'utilise également comme langage de
développement de prototype lorsqu'on a besoin d'une application fonctionnelle avant de
l'optimiser avec un langage de plus bas niveau. Il est particulièrement répandu dans le monde
scientifique, et possède de nombreuses bibliothèques optimisées destinées au calcul numérique.
Python a été conçu pour être un langage lisible. Il vise à être visuellement épuré. Par exemple,
il possède moins de constructions syntaxiques que de nombreux langages structurés tels que C,
Perl, ou Pascal. Les commentaires sont indiqués par le caractère croisillon (#). Les blocs sont
identifiés par l'indentation, au lieu d'accolades comme en C ou C++ ; ou de begin ... end comme
en Pascal ou Ruby. Une augmentation de l'indentation marque le début d'un bloc, et une
réduction de l'indentation marque la fin du bloc courant. Par convention (actuellement PEP8),
l'indentation est habituellement de quatre espaces en Python.
b. OpenCV :
OpenCV (pour Open Computer Vision) est une bibliothèque graphique libre, initialement
développée par Intel, spécialisée dans le traitement d'images en temps réel. La société de
robotique Willow Garage et la société ItSeez se sont succédé au support de cette bibliothèque.
Depuis 2016 et le rachat de ItSeez par Intel, le support est de nouveau assuré par Intel. Cette
bibliothèque est distribuée sous licence BSD. NVidia a annoncé en septembre 2010 qu'il
développerait des fonctions utilisant CUDA pour OpenCV.
Elle propose la plupart des opérations classiques en traitement bas niveau des images 8 :
Cette bibliothèque s'est imposée comme un standard dans le domaine de la recherche parce
qu'elle propose un nombre important d'outils issus de l'état de l'art en vision des ordinateurs tels
que :
Depuis la version 2.1 d'OpenCV l'accent a été mis sur les matrices et les opérations sur celles-
ci. En effet, la structure de base est la matrice. Une image peut être considérée comme une
matrice de pixel. Ainsi, toutes les opérations de bases des matrices sont disponibles, comme :
• La transposée.
• Calcul du déterminant.
• Inversion.
• Multiplication (par une matrice ou un scalaire).
• Calcul des valeurs propres.
Elle met également à disposition quelques fonctions d'interfaces graphiques, comme les
curseurs à glissière, les contrôles associés aux événements souris, ou bien l'incrustation de texte
dans une image.
c. Tensorflow :
TensorFlow est un outil open source d'apprentissage automatique développé par Google. Le
code source a été ouvert le 9 novembre 2015 par Google et publié sous licence Apache. Il est
fondé sur l'infrastructure DistBelief, initiée par Google en 2011, et est doté d'une interface pour
Python, Julia et R TensorFlow est l'un des outils les plus utilisés en IA dans le domaine de
l'apprentissage machine.
La version 1.0.0 est sortie le 11 février 2017 Alors que l'implémentation de référence tourne sur
un seul appareil, Tensorflow peut être lancé sur plusieurs CPU et GPU (avec des extensions
optionnelles telles que CUDA ou SYCL (en) pour GPGPU) . Tensorflow est disponible en
version 64- bits pour Linux, macOS, Windows et pour les plateformes mobiles sur Android et
iOS. Son architecture flexible permet le développement sur plusieurs variétés de plateformes
(CPU, GPU, TPU), allant du PC de bureaux à des clusters de serveurs et des mobiles aux
dispositifs de bords. En juin 2016, Jeff Dean a mentionné que 1 500 dépôts github
mentionnaient Tensorflow, dont seulement cinq étaient de Google.
d. Keras :
La bibliothèque Keras permet d'interagir avec les algorithmes de réseaux de neurones profonds
et d'apprentissage automatique, notamment Tensorflow, Theano, Microsoft Cognitive Toolkit
ou PlaidML. Conçue pour permettre une expérimentation rapide avec les réseaux de neurones
profonds, elle se concentre sur son ergonomie, sa modularité et ses capacites d’extension. Elle
a été développée dans le cadre du projet ONEIROS (Open-ended Neuro-Electronic Intelligent
Robot Operating System). Elle a été initialement écrite par François Chollet. L’intelligence
artificielle est aujourd’hui essentielle dans le monde numérique, que ce soit pour le
développement et l’utilisation de jeux vidéo (ou d’autres applications) ou pour les services Web,
les appareils et les machines. Les neural networks ou « réseaux neuronaux » en français,
constituent l’un des principaux domaines de recherche s’intéressant aux caractéristiques de base
de l’IA. Keras simplifie considérablement l’implémentation de ces réseaux. Découvrez ce
qu’offre cette bibliothèque open source et dans quelle mesure elle facilite la mise en place de
réseaux neuronaux. Keras est une bibliothèque open source écrite en Python (sous licence MIT)
basée principalement sur les travaux du développeur de Google François Chollet dans le cadre
du projet ONEIROS (Open-ended Neuro-Electronic Intelligent Robot Operating System). Une
première version du logiciel multiplateforme a été publiée le 28 mars 2015. Le but de cette
bibliothèque est de permettre la constitution rapide de réseaux neuronaux. Dans ce cadre, Keras
ne fonctionne pas comme un framework propre mais comme une interface de programmation
applicative (API) pour l’accès et la programmation de différents frameworks d’apprentissage
automatique. Theano, Microsoft Cognitive Toolkit (anciennement CNTK) et TensorFlow font
notamment partie des frameworks pris en charge par Keras.
2. Matlab :
La programmation d'une carte Raspberry Pi™ implique souvent de travailler avec des images,
de la vidéo, de l'audio et autres données de capteurs. MATLAB® et Simulink® permettent aux
utilisateurs d'analyser et visualiser rapidement ces données et de programmer leur carte
Raspberry Pi en conséquence. Les produits prennent en charge deux méthodes de travail :
• Lecture, écriture et analyse des données à partir des capteurs et caméras Raspberry Pi.
• Développement d'algorithmes s'exécutant de manière autonome sur la carte Raspberry
Pi.
MATLAB est un logiciel de calcul matriciel à syntaxe simple. Avec ses fonctions spécialisées,
MATLAB peut être aussi considéré comme un langage de programmation adapté pour les
problèmes scientifiques. MATLAB est un interpréteur : les instructions sont interprétées et
exécutées ligne par ligne. MATLAB fonctionne dans plusieurs environnements tels que
Xwindows, Windows, Macintosh. Il existe deux modes de fonctionnement :
• Mode interactif : MATLAB exécute les instructions au fur et à mesure qu'elles sont
données par l'usager.
• Mode exécutif : MATLAB exécute ligne par ligne un "fichier M" (programme en
langage MATLAB).
• Fenêtre Commande : Dans cette fenêtre, l'usager donne les instructions et MATLAB
retourne les résultats.
• Fenêtres Graphique : MATLAB trace les graphiques dans ces fenêtres.
• Fichiers M : Ce sont des programmes en langage MATLAB (écrits par l'usager).
• Toolboxes : Ce sont des collections de fichiers M développés pour des domaines
d'application spécifiques (Signal Processing Toolbox, System Identification Toolbox,
Control System Toolbox, u-Synthesis and Analysis Toolbox, Robust Control Toolbox,
Optimization Toolbox, Neural Network Toolbox, Spline Toolbox, Chemometrics
Toolbox, Fuzzy Logic Toolbox, etc.)
• Simulink : C'est l'extension graphique de MATLAB permettant de travailler avec des
diagrammes en blocs.
• Blocksets : Ce sont des collections de blocs Simulink développés pour des domaines
d'application spécifiques (DSP Blockset, Power System Blockset, etc.).
On peut échanger des modèles avec TensorFlow™ et PyTorch grâce au format ONNX et
importer des modèles depuis TensorFlow-Keras et Caffe. La toolbox supporte l'apprentissage
par transfert avec de nombreux modèles pré-entraînés, parmi lesquels DarkNet-53, ResNet-50,
NASNet et SqueezeNet.
clouds, tels que les instances GPU Amazon EC2® et NVIDIA® GPU Cloud (avec MATLAB
Parallel Server™).
La bibliothèque de calcul Arm offre des performances supérieures aux autres alternatives open
source et une prise en charge immédiate des nouvelles technologies Arm, par ex. SVE2.
• Principales caractéristiques :
• Plus de 100 fonctions d'apprentissage automatique pour CPU et GPU
• Algorithmes de convolution multiples (GEMM, Winograd, FFT et Direct)
• Prise en charge de plusieurs types de données : FP32, FP16, int8, uint8, BFloat16
• Optimisation de la microarchitecture pour les primitives ML clés
• Options de construction hautement configurables permettant des binaires légers
• Techniques d'optimisation avancées telles que Kernel Fusion, Fast Math Enablement et
utilisation des textures
• Réglage spécifique à l'appareil et à la charge de travail à l'aide du tuner Open CL et de
l'heuristique optimisée GEMM.
NB : Pour construire est configurer la librairie Arm compute il suffit de suivre les étapes
dans les liens [13] et [14].
c. Matlab coder :
MATLAB® Coder™ génère du code C et C++ à partir du code MATLAB pour une variété de
plates-formes matérielles, des systèmes de bureau au matériel embarqué. Il prend en charge la
plupart du langage MATLAB et une large gamme de boîtes à outils. Vous pouvez intégrer le
code généré dans vos projets en tant que code source, bibliothèques statiques ou bibliothèques
dynamiques. Le code généré est lisible et portable. Vous pouvez le combiner avec des éléments
clés de votre code et bibliothèques C et C++ existants. Vous pouvez également empaqueter le
code généré en tant que fonction MEX à utiliser dans MATLAB.
Lorsqu'il est utilisé avec Embedded Coder®, MATLAB Coder fournit des personnalisations de
code, des optimisations spécifiques à la cible, la traçabilité du code et la vérification du logiciel
dans la boucle (SIL) et du processeur dans la boucle (PIL).
NB : pour télécharger est utiliser ce package on peut suivre les étapes dans les liens [2] et
[18].
Conclusion :
Ce chapitre était un chapitre introductif dans lequel j’ai présenté brièvement l’entreprise
d’accueil ainsi que la description de notre projet, sans contexte logiciel et matériel.
Introduction :
Afin de distinguer entre l’ensemble des panneaux de limitation de vitesse on aura besoin d’un
réseau de neurones capable d’exécuter un traitement d’image sur les images en entrée et de
prédire le résultat adéquat. Le type de réseau de neurone le plus approprié est le réseau de
neurones convolutifs (CNN).
• Couche convolutive.
• Couche de mise en commun.
• Couche entièrement connectée (FCL).
La couche convolutive est la première couche d'un réseau convolutif. Alors que les couches
convolutives peuvent être suivies de couches convolutives supplémentaires ou de couches de
regroupement, la couche entièrement connectée est la couche finale. Avec chaque couche, le
CNN augmente dans sa complexité, identifiant de plus grandes portions de l'image. Les couches
précédentes se concentrent sur des caractéristiques simples, telles que les couleurs et les bords.
Au fur et à mesure que les données d'image progressent à travers les couches du CNN, elles
commencent à reconnaître des éléments ou des formes plus grands de l'objet jusqu'à ce qu'elles
identifient enfin l'objet visé.
1. La couche de convolution :
La couche convolutive est la pierre angulaire d'un CNN, et c'est là que se produit la majorité
des calculs. Son objectif final est d'extraire des caractéristiques propres à chaque image. Par
exemple, supposons que nous essayons de déterminer si une image contient un vélo. On peut
considérer le vélo comme une somme de pièces. Il est composé d'un cadre, d'un guidon, de
roues, de pédales, etc. Chaque partie individuelle du vélo constitue un modèle de niveau
inférieur dans le réseau neuronal, et la combinaison de ses parties représente un modèle de
niveau supérieur, créant une hiérarchie de fonctionnalités au sein du CNN.
La couche convolutive nécessite quelques composants, qui sont des données d'entrée, un filtre
et une carte de caractéristiques, et elle comporte quelques composants et paramètres qui doivent
être clarifiés, à savoir :
• Le noyau/détecteur de fonctionnalités/Filtre.
• La carte des caractéristiques/la carte d'activation/la caractéristique convoluée.
• La foulée (stride).
• Le rembourrage (padding).
Ainsi, ils seront expliqués et explorés au fur et à mesure que les choses avancent.
Dans notre cas, l'entrée est une image en noir et blanc, qui est constituée d'une matrice de pixels
en 2D. Cela signifie que l'entrée aura trois dimensions - une hauteur, une largeur et une
profondeur égale à 1 -. Nous avons également un détecteur de caractéristiques, également connu
sous le nom de noyau ou de filtre, qui se déplacera à travers les champs récepteurs de l'image,
vérifiant si la caractéristique est présente. Ce processus est connu sous le nom de convolution.
Le détecteur de caractéristiques est un réseau de poids bidimensionnel (2D) qui représente une
partie de l'image. Ses paramètres sont automatiquement choisis par le modèle lors de
l'entraînement.
Bien qu'ils puissent varier en taille, la taille du filtre est généralement une matrice 3x3. Cela
détermine également la taille du champ récepteur.
Le filtre est ensuite appliqué à une zone de l'image, et un produit scalaire est calculé entre les
pixels d'entrée et le filtre. Ce produit scalaire est ensuite introduit dans un tableau de sortie.
Le filtre commence du début de l’image en haut à gauche, ensuite, le filtre se déplace vers la
droite avec une certaine valeur de foulée jusqu'à ce qu'il analyse toute la largeur. En continuant,
il saute au début (à gauche) de l'image avec la même valeur de foulée et répète le processus
jusqu'à ce que l'image entière soit parcourue.
Notez que la foulée est la distance, ou le nombre de pixels, que le noyau se déplace sur la
matrice d'entrée. Alors que des valeurs de foulée de deux ou plus sont rares, une foulée plus
grande donne une sortie plus petite.
Un autre paramètre que nous pouvons ajuster lors de la convolution est le remplissage, qui est
généralement utilisé lorsque les filtres ne correspondent pas à l'image d'entrée. Cela définit tous
les éléments qui tombent en dehors de la matrice d'entrée à zéro, produisant une sortie plus
grande ou de taille égale
Cela permet d'éviter la perte de données et de préserver l'ensemble de l'image, y compris ses
bords s'ils sont importants. Mais plus il est grand, plus la taille de la carte des caractéristiques
sera grande.
Par exemple, dans la figure 5, nous utilisons un remplissage égal à 1 pixel, et pour la figure 6,
nous n'avons utilisé aucun remplissage.
Après chaque opération de convolution, un CNN applique une transformation d'unité linéaire
rectifiée (ReLU) à la carte des caractéristiques, la couche RELU appliquera une fonction
d'activation par élément, telle que le seuillage max (0, x) à zéro.
Cette couche remplace toutes les valeurs négatives reçues en entrée par des zéros. L'intérêt de
ces couches d'activation est de rendre le modèle non linéaire et donc plus complexe.
Le principal avantage de l'utilisation de la fonction ReLU par rapport aux autres fonctions
d'activation est qu'elle n'active pas tous les neurones en même temps, puisque seul un certain
nombre de neurones sont activés, la fonction ReLU est beaucoup plus efficace en termes de
calcul par rapport aux autres fonctions d'activation.
En outre, il est utile pour extraire des caractéristiques dominantes qui sont invariantes en
rotation et en position, maintenant ainsi le processus d'entraînement efficace du modèle.
L'opération de mise en commun balaie un filtre sur toute l'entrée comme la couche convolutive,
mais la différence est que ce filtre n'a pas de poids. Au lieu de cela, le noyau applique une
fonction d'agrégation aux valeurs dans le champ réceptif, remplissant le tableau de sortie.
• Max pooling : lorsque le filtre se déplace sur l'entrée, il sélectionne le pixel avec la
valeur maximale à envoyer au tableau de sortie. Soit dit en passant, cette approche a
tendance à être utilisée plus souvent que la mise en commun moyenne.
• Average pooling : au fur et à mesure que le filtre se déplace sur l'entrée, il calcule la
valeur moyenne dans le champ récepteur à envoyer au tableau de sortie.
Bien que de nombreuses informations soient perdues dans la couche de mise en commun, cela
présente également un certain nombre d'avantages pour le CNN. Ils aident à réduire la
complexité, à améliorer l'efficacité et à limiter le risque de surapprentissage.
dans les couches partiellement connectées. Cependant, dans la couche entièrement connectée,
chaque nœud de la couche de sortie se connecte directement à un nœud de la couche précédente.
Comme nous pouvons le voir sur la figure, la sortie de mise en commun est aplatie puis injectée
dans la couche entièrement connectée qui est un perceptron multicouche typique qui a n sorties,
avec n représentant le nombre de classes, cette couche effectue la tâche de classification basée
sur les caractéristiques extraites à travers les couches précédentes et leurs différents filtres.
Dans la figure ci-dessous, nous pouvons comprendre le processus d'aplatissement à partir d'une
simple matrice 3x3 :
Alors que les couches convolutives et de mise en commun ont tendance à utiliser les fonctions
ReLu, les couches FCL exploitent généralement une fonction d'activation SoftMax pour classer
les entrées de manière appropriée, produisant une probabilité de 0 à 1.
Ainsi, la sortie de cette couche qui est la sortie finale serait un vecteur (n x1) contenant des
valeurs entre 0 et 1 qui représentent la probabilité pour chaque classe.
Conclusion :
En général, CNN a tendance à être un moyen plus puissant et plus précis de résoudre les
problèmes de classification. ANN est toujours dominante pour les problèmes où les ensembles
de données sont limités et les entrées d'images ne sont pas nécessaires. En raison de la capacité
de CNN à visualiser les images sous forme de données, il s'agit de la solution la plus répandue
pour les problèmes de vision par ordinateur et d'apprentissage automatique dépendant de
l'image.
Il existe diverses architectures de CNN disponibles qui ont joué un rôle clé dans la création
d'algorithmes qui alimentent et alimenteront l'IA dans son ensemble dans un avenir prévisible.
Certains d'entre eux ont été énumérés ci-dessous :
• LeNet.
• AlexNet.
• VGGNet.
• GoogLeNet.
• ResNet.
• ZFNet.
Chapitre 3 : Le système de
reconnaissance des panneaux de
limitation de vitesse
Introduction :
Ce chapitre représente toutes les étapes de la création du système de reconnaissance des
panneaux de limitation de vitesse :
Les données utilisées sans des panneaux de signalisation d’une forme circulaire qui seront
groupés selon le besoin.
Puisque dans ce projet on va se concentrer sur les panneaux de limitation de vitesse Le système
créé sera composé de deux modèle :
• Une classe des Panneaux de limitation de vitesse : c’est un ensemble d’image qui
contient panneaux de limitation de vitesse avec des vitesses qui varie entre 20 et 130.
• Une classe des autres panneaux de signalisation : elle contient l’ensemble d’images
des autres panneaux de signalisation de forme circulaire.
La classe des panneaux de limitation de vitesse sera ensuite divisée en sous classes, chaque
classe représentera une vitesse précise.
L’entrainement des modèles avec cette base de données nous à permit d’avoir une bonne
accuracy environ 97% pour le modèle qui détecte si le panneau est un panneau de limitation de
vitesse ou pas et environ 90% pour le deuxième model). Mais ils souffraient d’un problème,
c’est le fait qu’ils ne pouvaient pas détecter les panneaux avec une très grande ou très faible
luminosité, d’où la nécessité d’une autre base de données.
Avantages Inconvénients
- Des arrière-plans différents pour - Pas de rotation à l’image.
chaque image. - Pas de perspective.
- Ajout du flou. - Pas de décalage de l’image.
- Changement d’échelle. - Un grand écart entre les nombres
- Le dégradé de l'luminosité. d’images pour chaque classe
- Brouillard. (spécialement le nombre de chaque
- Bruit. sous classe des panneaux de
- Des cas de très forte luminosité. limitation de vitesse).
- Des cas de très faible luminosité. - Ne contient pas l’ensemble des
panneaux.
NB : la qualité des images est dû au fait que leur taille originale est : (32 * 32).
C’est vrai qu’avec cette base de données on a pu avoir une très bonne accuracy (environ 98%
pour le modèle qui détecte si le panneau est un panneau de limitation de vitesse ou pas et environ
95% pour le deuxième model). Mais le modèle ne peut reconnaitre des panneaux avec une forte
rotation ou perspective. Cela invoque la recherche d’une troisième base de données.
C’est vrai que le mélange des deux bases de données nous a permis d’éliminer les problèmes
cités avant, mais il provoquait un autre problème qui est le fait que les images de la première
base de données avaient un contour rouge et les images de la deuxième base de données avaient
un contour bleu.
La plus simple manière de résoudre ce problème qui est la différence de couleur de contour est
de convertir toutes les images de base de données en niveaux de gris. Cela nous a permis non
seulement de créer une compatibilité entre les deux images mais aussi d’augmenter l’accuracy
des modèles.
a. Le premier modèle :
Ce modèle a comme mission de reconnaitre si le panneau est un panneau de limitation de vitesse
ou c’est un autre panneau de signalisation. Pour cela on va essayer de diviser notre base de
données en deux classes :
Comme mentionné nos modèles seront basés sur l’architecture des réseaux de neurones
convolutifs. Alors notre modèle est constitué des couches suivantes :
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 40, 40, 64) 640
_________________________________________________________________
activation (Activation) (None, 40, 40, 64) 0
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 20, 20, 64) 0
_________________________________________________________________
L’entrée de notre modèle est une matrice de taille (42 * 42* 1), ce modèle est composé de deux
couches convolutifs :
Une couche Flatten pour aplatir les données traitées et deux couches totalement connectées.
Optimisateur Adam
La fonction de perte Categorical_Crossentropy
Métriques CategoricalAccuracy
Nombres d’époques 20
Taille du lot (batch size) 64
b. Le deuxième modèle :
Ce modèle nous a permis de reconnaitre la valeur de la vitesse sur le panneau détecté comme
panneau de limitation de vitesse pour cela on va essayer de diviser la partie de notre base de
données qui contient les panneaux de limitation de vitesse en sous classes, chaque classe va
contenir des images des panneaux de limitation de vitesse avec la même valeur de vitesse, le
nombre d’image pour chaque classe est comme suite :
60 3260
70 3770
80 3650
90 2000
100 3290
110 2000
120 2520
130 2000
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 40, 40, 128) 1280
_________________________________________________________________
dropout (Dropout) (None, 40, 40, 128) 0
_________________________________________________________________
activation (Activation) (None, 40, 40, 128) 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 38, 38, 128) 147584
_________________________________________________________________
dropout_1 (Dropout) (None, 38, 38, 128) 0
_________________________________________________________________
activation_1 (Activation) (None, 38, 38, 128) 0
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 19, 19, 128) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 17, 17, 256) 295168
_________________________________________________________________
dropout_2 (Dropout) (None, 17, 17, 256) 0
_________________________________________________________________
activation_2 (Activation) (None, 17, 17, 256) 0
_________________________________________________________________
conv2d_3 (Conv2D) (None, 15, 15, 256) 590080
_________________________________________________________________
dropout_3 (Dropout) (None, 15, 15, 256) 0
_________________________________________________________________
activation_3 (Activation) (None, 15, 15, 256) 0
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 7, 7, 256) 0
_________________________________________________________________
flatten (Flatten) (None, 12544) 0
_________________________________________________________________
dense (Dense) (None, 512) 6423040
_________________________________________________________________
dropout_4 (Dropout) (None, 512) 0
_________________________________________________________________
dense_1 (Dense) (None, 12) 6156
=================================================================
L’entrée de notre modèle est une matrice de taille (42 * 42* 1), ce modèle est composé de quatre
couches convolutifs :
• Les deux premières avec 128 filtres avec une fonction d’activation Relu.
• Les deux deuxièmes avec 256 filtres avec une fonction d’activation Relu.
• Chaque deux couches sont liées à une couche de Maxpooling.
• Chaque couche est liée à une couche dropout. Cette couche permet de désactiver des
sorties de neurones aléatoirement afin de permettre d’accélérer l’apprentissage, cela
revient à simuler un ensemble de modèle différents et à les apprendre conjointement.
Chaque neurone étant possiblement inactif pendant une itération d'apprentissage, cela
force chaque unité à « bien apprendre » indépendamment des autres et évite ainsi la «
coadaptation ».
Une couche Flatten pour aplatir les données traitées et deux couches totalement connectées dont
la première est liée c’est une couche dropout.
Optimisateur Adam
La fonction de perte Categorical_Crossentropy
Métriques CategoricalAccuracy
Nombres d’époques 20
Taille du lot (batch size) 128
Lorsque nous générons le code pour la prédiction, le package de support Raspberry Pi crée
l'exécutable sur le matériel. À l'aide des modèles qu’on dispose, l'exécutable classifie les images
dans la bonne catégorie de vitesses.
Pour configurer la connexion nous avons besoin des packages et des outils suivants :
Nous insérons la carte Micro SD dans la Raspberry Pi, nous connectons l'extrémité micro du
câble USB au Raspberry Pi et l'extrémité normale du câble USB à l'ordinateur et nous attendons
que la LED PWR sur le matériel commence à clignoter. Ensuite nous tapons dans la fenêtre de
commandes MATLAB r=raspi().
Maintenant que la connexion était bien effectuée nous passons à La génération et le déploiement
de notre code Matlab vers la Raspberry :
Alors pour cela les librairies Matlab Coder, Deep Learning ToolBox, Arm Compute cités dans
la partie du contexte logiciel doivent être installés et les variables d’environnements pour les
librairies et les compilateurs doivent être configurés. Par la suite nous avons suivi les étapes
dans le lien [8].
La fonction deploy lance la génération de code de notre fonction. Une fois la génération de code
terminée, MATLAB génère un rapport de génération de code. Utilisez ce rapport pour déboguer
notre fonction pour toute erreur de génération et avertissement dans le code généré, voilà le
rapport généré dans notre cas.
Après avoir réussi à générer le code, le package charge et exécute l'algorithme de classification
d'objets en tant qu'exécutable sur le matériel. L'exécutable commence à classer les objets dans
la vidéo acquise et affiche les étiquettes prédites. Pour afficher l'écran Raspberry Pi, utilisez
une visionneuse VNC et effectuez une session à distance sur le matériel pour obtenir l'affichage.
Après avoir réussi la classification des panneaux de limitation de vitesses dans les bonnes
catégories nous avons procédé à la régulation du moteur DC selon la valeur de chaque panneau
normalisé à l’aide des deux fonctions Matlab writePWMDutyCycle et writePWMFrequency.
Le PWM utilise une implémentation logicielle permettant à toutes les broches GPIO de la carte
matérielle du Raspberry Pi de produire un signal PWM. Chaque broche PWM génère une forme
d'onde carrée avec une fréquence, un cycle de service ou une tension moyenne variables. Un
rapport cyclique de 0 signifie que la forme d'onde est toujours faible et un rapport cyclique de
1 signifie que la forme d'onde est toujours élevée.
Pour utiliser une broche PWM, reconfigurez l'une des broches GPIO à usage multiple en tant
que broche PWM.
Lorsque les variables des données proviennent de distributions éventuellement différentes (et
non normales), d’autres transformations peuvent être nécessaires. Une autre possibilité consiste
à normaliser les variables pour amener les données sur l’échelle de 0 à 1 en soustrayant le
minimum et en divisant par le maximum de toutes les observations.
Cela préserve la forme de la distribution de chaque variable tout en les rendant facilement
comparables sur la même « échelle ».
𝒙 − 𝒙𝒎𝒊𝒏
𝒙𝒏𝒐𝒓𝒎 = ∗ (𝒙′ 𝒎𝒂𝒙 − 𝒙′ 𝒎𝒊𝒏 ) + 𝒙′𝒎𝒊𝒏
𝒙𝒎𝒂𝒙 − 𝒙𝒎𝒊𝒏
Conclusion :
Nos modèles donnent les bonnes prédictions avec les différentes images. Nous avons également
essayé de nombreuses images des différentes classes avec différentes formes et obtenons
toujours les résultats attendus, et nous sommes impatients de le démontrer. Enfin, nous pouvons
conclure que nos modèles sont performants.
Conclusion générale
Si la reconnaissance de panneaux est globalement parfaitement fiable, elle n’en reste pas moins
limitée dans certaines situations, et ne remplace donc pas la vigilance du conducteur.
Les systèmes de reconnaissance de panneaux de signalisation sont d’une très grande fiabilité
par rapport à d’autres aides à la navigation, comme les systèmes GPS par exemple. Car même
si certains GPS peuvent afficher sur leur écran les panneaux spécifiant les limitations de vitesse
en vigueur, le système ne sera pas toujours au courant des changements de limitation pratiqués
dans une zone spécifique par exemple. C’est donc un des principaux points forts de la
reconnaissance des panneaux, qui permet de suivre en permanence la limitation de vitesse
comme elle est affichée le long des routes.
Index
def bruit(image_orig):
h, w, c=image_orig.shape
n=np.random.randn(h, w, c)*random.randint(5, 30)
return np.clip(image_orig+n, 0, 255).astype(np.uint8)
def modif_img(img):
h, w, c=img.shape
# Ajouter du flou :
if np.random.randint(3):
k_max=3
kernel_blur=np.random.randint(k_max)*2+1
img=cv2.GaussianBlur(img, (kernel_blur, kernel_blur), 0)
# Appliquer de la perspective
if np.random.randint(2):
a=int(max(w, h)/5)+1
pts1=np.float32([[0, 0], [w, 0], [0, h], [w, h]]) # les bords de l'image
pts2=np.float32([[0+random.randint(-a, a), 0+random.randint(-a, a)],
[w-random.randint(-a, a), 0+random.randint(-a, a)],
[0+random.randint(-a, a), h-random.randint(-a, a)],
[w-random.randint(-a, a), h-random.randint(-a, a)]])
M=cv2.getPerspectiveTransform(pts1,pts2) # Matrice de déformation
img=cv2.warpPerspective(img, M, (w, h))
# Décalage de l'image
if np.random.randint(2):
r=random.randint(0, 5)
h2=int(h*0.9)
w2=int(w*0.9)
if r==0:
img=img[0:w2, 0:h2]
elif r==1:
img=img[w-w2:w, 0:h2]
elif r==2:
img=img[0:w2, h-h2:h]
elif r==3:
img=img[w-w2:w, h-h2:h]
img=cv2.resize(img, (h, w))
# Changment d'echelle
if np.random.randint(2):
r=random.randint(1, int(max(w, h)*0.15))
img=img[r:w-r, r:h-r]
img=cv2.resize(img, (h, w))
if not np.random.randint(4):
t=np.empty((h, w, c) , dtype=np.float32)
for i in range(h):
for j in range(w):
for k in range(c):
t[i][j][k]=(i/h)
M=cv2.getRotationMatrix2D((int(w/2), int(h/2)), np.random.randint(4)*90, 1)
t=cv2.warpAffine(t, M, (w, h))
img=(cv2.multiply((img/255).astype(np.float32), t)*255).astype(np.uint8)
# changement de l'uminosité
img=change_gamma(img, random.uniform(0.6, 1.0), -np.random.randint(50))
#Ajouter du bruit
img=bruit(img)
return img
import os
def lire_images_panneauxir_images_panneaux(d):
tab_panneau=[]
if not os.path.exists(dir_images_panneaux):
quit("Le repertoire d'image n'existe pas: {}".format(dir_images_panneaux))
files=os.listdir(dir_images_panneaux)
if files is None:
quit("Le repertoire d'image est vide: {}".format(dir_images_panneaux))
return tab_panneau
tab_panneau=lire_images_panneaux('images_panneaux')
print(tab_panneau)
size = 42
for name in tab_panneau:
for i in range(0,2000):
img = cv2.imread('images_panneaux/{}.png'.format(name))
img=cv2.resize(img, (size, size), cv2.INTER_LANCZOS4)
img = modif_img(img)
cv2.imwrite("Dataset/images/{}/{}_{}.png".format(name,name,i),img)
cv2.imwrite("Dataset_is_panneau/images/is_panneau/{}_{}.png".format(name,i),img)
print("done!!! {}".format(name))
tab_panneau = lire_images_panneaux('images_autres_panneaux')
print(tab_panneau)
size = 42
for name in tab_panneau:
for i in range(0,200):
img = cv2.imread('images_autres_panneaux/{}.svg.png'.format(name))
img=cv2.resize(img, (size, size),cv2.INTER_LANCZOS4)
img = modif_img(img)
cv2.imwrite("Dataset_is_panneau/images/is_not_panneau/{}_{}.png".format(name,i),img)
print("done!!! {}".format(name))
2. Le premier modèle :
import cv2
import os
data_path='Dataset_is_panneau'
categories=os.listdir(data_path)
data_path='Dataset_is_panneau/images'
classes_path=os.listdir(data_path)
classesf=os.listdir(data_path)
print(classesf)
labels_classes=[i for i in range(len(classesf))]
print(labels_classes)
data_path='Dataset_is_panneau'
label_classes_dict=dict(zip(classesf,labels_classes))
print(labels_classes)
print(categories)
print(label_classes_dict)
import numpy as np
img_size=42
data=[]
target=[]
c=0
minValue = 70
for category in categories:
cat_path=os.path.join(data_path,category)
print(cat_path)
cat_names=os.listdir(cat_path)
print(cat_names)
for classes in cat_names:
folder_path=os.path.join(data_path,category,classes)
print(folder_path)
img_names=os.listdir(folder_path)
#print(img_names)
for img_name in img_names:
#print(img_name)
img_path=os.path.join(folder_path,img_name)
img=cv2.imread(img_path,0)
try:
resized=cv2.resize(img,(img_size,img_size))
data.append(resized)
#print(data)
target.append(label_classes_dict[classes])
except Exception as e:
print('Exception:',e)
print(len(data))
datanp=np.array(data)
datanp.shape
targetnp=np.array(target)
targetnp.shape
import numpy as np
data=np.array(data)/255.0
data=np.reshape(data,(data.shape[0],42,42,1))
print(data[1:10])
target=np.array(target)
from tensorflow.keras.utils import to_categorical
target=to_categorical(target)
print(data.shape)
print(target.shape)
np.save('data_img_is_panneau',data)
np.save('target_is_panneau',target)
data=np.load('data_img_is_panneau.npy')
target=np.load('target_is_panneau.npy')
print(train_data.shape)
print(train_target.shape)
print(test_data.shape)
print(test_target.shape)
print(train_target[2000])
import tensorflow as tf
from tensorflow.keras import layers, models
import os
import cv2
size = 42
def is_panneau_model():
model=tf.keras.Sequential()
model.add(layers.Conv2D(128, 3, strides=1))
model.add(layers.Activation('relu'))
model.add(layers.MaxPool2D(pool_size=2, strides=2))
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(2, activation='softmax'))
return model
model_is_panneau=is_panneau_model()
model_is_panneau.summary()
model_is_panneau.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=[tf.keras.metrics.CategoricalAccuracy()])
checkpoint = ModelCheckpoint('model-{epoch:03d}.model',
monitor='val_loss',
verbose=0,
save_best_only=True,
mode='auto')
history=model_is_panneau.fit(train_data,
train_target,
shuffle=True,
batch_size=64,
epochs=20,
callbacks=[checkpoint],
validation_split=0.3)
print(model_is_panneau.evaluate(test_data,test_target))
print("Done !")
import numpy as np
import pandas as pd
import seaborn as sn
from sklearn.metrics import classification_report,confusion_matrix
model_is_panneau=tf.keras.models.load_model('model_is_panneau_2000_5nb.h5')
3. Le deuxième modèle :
import cv2
import os
data_path='Dataset'
categories=os.listdir(data_path)
labels=[i for i in range(len(categories))]
label_dict=dict(zip(categories,labels)) #empty dictionary
print(label_dict)
print(categories)
print(labels)
data_path='Dataset/images'
classes_path=os.listdir(data_path)
classesf=os.listdir(data_path)
print(classesf)
labels_classes=[i for i in range(len(classesf))]
print(labels_classes)
data_path='Dataset'
label_classes_dict=dict(zip(classesf,labels_classes))
print(labels_classes)
print(categories)
print(label_classes_dict)
import numpy as np
img_size=42
data=[]
target=[]
c=0
minValue = 70
for category in categories:
cat_path=os.path.join(data_path,category)
print(cat_path)
cat_names=os.listdir(cat_path)
print(cat_names)
print(len(data))
datanp=np.array(data)
datanp.shape
targetnp=np.array(target)
targetnp.shape
import numpy as np
data=np.array(data)/255.0
data=np.reshape(data,(data.shape[0],42,42,1))
print(data[1:10])
target=np.array(target)
new_target=to_categorical(target)
print(data.shape)
print(new_target.shape)
np.save('data_img',data)
np.save('target',new_target)
data=np.load('data_img.npy')
target=np.load('target.npy')
import tensorflow as tf
from tensorflow.keras import layers, models
import os
import cv2
size = 42
def panneau_model(nbr_classes):
model=tf.keras.Sequential()
model.add(layers.Conv2D(128, 3, strides=1))
model.add(layers.Dropout(0.2))
model.add(layers.Activation('relu'))
model.add(layers.MaxPool2D(pool_size=2, strides=2))
model.add(layers.Conv2D(256, 3, strides=1))
model.add(layers.Dropout(0.3))
model.add(layers.Activation('relu'))
model.add(layers.Conv2D(256, 3, strides=1))
model.add(layers.Dropout(0.4))
model.add(layers.Activation('relu'))
model.add(layers.MaxPool2D(pool_size=2, strides=2))
model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(nbr_classes, activation='softmax'))
return model
model_panneau=panneau_model(len(labels_classes))
model_panneau.summary()
model_panneau.compile( optimizer='adam',
loss='categorical_crossentropy',
metrics=[tf.keras.metrics.CategoricalAccuracy()])
checkpoint = ModelCheckpoint('model-{epoch:03d}.model',
monitor='val_loss',
verbose=0,
save_best_only=True,
mode='auto')
history=model_panneau.fit(train_data,
train_target,
shuffle=True,
batch_size=128,
epochs=20,
callbacks=[checkpoint],
validation_split=0.3)
print(model_panneau.evaluate(test_data,test_target))
import numpy as np
import pandas as pd
import seaborn as sn
from sklearn.metrics import classification_report,confusion_matrix
model_panneau=tf.keras.models.load_model('model_panneu_2000_5nb.h5')
sn.heatmap(df_cm, annot=True,
fmt='d',
xticklabels=classesf,
yticklabels=classesf)
%motor configuration :
configurePin(raspiObj, 25, 'PWM');
configurePin(raspiObj, 23, 'DigitalOutput');
configurePin(raspiObj, 24, 'DigitalOutput');
writePWMFrequency(raspiObj, 25, 2000);
writeDigitalPin(raspiObj,24,1);
writeDigitalPin(raspiObj,23,0);
writePWMDutyCycle(raspiObj, 25,1);
% Main loop
start = tic;
fprintf('Entering into while loop.\n');
while true
%Capture image from webcam
img = snapshot(cam);
elapsedTime = toc(start);
%Process frames at 1 per second
if elapsedTime > 1
%Resize the image
imageBWAdjusted = rgb2gray(img);
imgSizeAdjusted = imresize(imageBWAdjusted,inputSize(1:2));
labelStr1 = cellstr(label1);
if labelStr1{:} == a
[label,score] = net.classify(imgSizeAdjusted);
labelStr = cellstr(label);
textToDisplay = sprintf('Label : %s \nScore : %s',is,labelStr{:});
M = str2double(labelStr{:});
M = (M - 20)*(1 - 0.3)/(130 - 20) + 0.3;
writePWMDutyCycle(raspiObj, 25,M);
else
textToDisplay = sprintf('Label : %s \nScore : 0',isnot);
end
start = tic;
end
3. Le script de déploiement :
r = raspi;
board = targetHardware('Raspberry Pi');
board.CoderConfig.TargetLang = 'C++'
dlcfg = coder.DeepLearningConfig('arm-compute');
dlcfg.ArmArchitecture = 'armv7';
r.system('strings $ARM_COMPUTELIB/lib/libarm_compute.so | grep arm_compute_versio
| cut -d\ -f 1')
dlcfg.ArmComputeVersion = '19.05';
board.CoderConfig.DeepLearningConfig = dlcfg
deploy(board,'code')
Webographie
[1] https://fr.mathworks.com/discovery/raspberry-pi-programming-matlab-simulink.html
[2] https://fr.mathworks.com/videos/install-the-matlab-support-package-for-raspberry-pi-
94266.html?requestedDomain=
[3] https://fr.mathworks.com/videos/deploy-matlab-algorithms-on-raspberry-pi-
1591965724601.html
[4] https://fr.mathworks.com/videos/deploy-an-edge-detection-algorithm-on-raspberry-pi-
1591967219707.html
[5] https://fr.mathworks.com/help/supportpkg/raspberrypiio/ref/raspi.html
[6] https://www.mathworks.com/videos/deep-learning-with-raspberry-pi-and-matlab-
1567791721457.html
[7] https://fr.mathworks.com/help/supportpkg/raspberrypiio/ref/classify-image-received-over-
ssh-in-raspberry-pi.html
[8] https://fr.mathworks.com/help/supportpkg/raspberrypiio/ref/identify-objects-within-video-
using-resNet-50-on-raspberry-pi-hardware.html
[9] https://fr.mathworks.com/help/supportpkg/raspberrypiio/ref/configurepin.html
[10] https://fr.mathworks.com/help/supportpkg/raspberrypiio/ref/writepwmdutycycle.html
[11] https://fr.mathworks.com/help/supportpkg/raspberrypiio/ref/writepwmfrequency.html
[12] https://laptrinhx.com/raspberry-pi-l298n-interface-tutorial-control-a-dc-motor-with-
l298n-and-raspberry-pi-2517629701/
[13] https://www.mathworks.com/matlabcentral/answers/455590-matlab-coder-how-do-i-
build-the-arm-compute-library-for-deep-learning-c-code-generation-and-deplo
[14] https://www.mathworks.com/matlabcentral/answers/455591-matlab-coder-how-do-i-
setup-the-environment-variables-on-arm-targets-to-point-to-the-arm-compute-li
[15] https://www.datanovia.com/en/fr/blog/comment-normaliser-et-standardiser-les-donnees-
dans-r-pour-une-visualisation-en-heatmap-magnifique/
[16] https://www.arm.com/why-arm/technologies/compute-library
[17]https://fr.mathworks.com/products/deep-
learning.html#:~:text=Deep%20Learning%20Toolbox%E2%84%A2%20offre,pr%C3%A9%
2Dentra%C3%AEn%C3%A9s%20et%20des%20applications.
[18] https://fr.mathworks.com/help/supportpkg/raspberrypiio/
[19] https://www.youtube.com/watch?v=PvD5POjXw8Q&t=1434s
[20] https://opendatascience.com/a-beginners-guide-to-understanding-convolutional-neural-
networks/
[21] https://towardsdatascience.com/basics-of-the-classic-cnn-a3dce1225add