Introduction

Ce tutoriel requiert des bases en Arduino et en électronique. Nous allons voir toutes les étapes essentielles pour comprendre, concevoir et mettre en oeuvre un système de détection de couleurs sur Arduino.

Utilisation des capteurs

Dans un premier temps, nous aurons besoin de capteurs pour collecter les données. A titre d’exemple, nous pouvons utiliser le veml6040 de chez Vishay et l'APD-9250 de chez Artekit. Ces deux capteurs sont très simples d’utilisation et possèdent de nombreuses bibliothèques déjà existantes pour les utiliser plus facilement.

Pour le premier, je recommande la bibliothèque de thewknd disponible sur github. Son fonctionnement ainsi que son utilisation y sont expliqués.

Pour le second, voici la page officielle du fabricant avec toutes les informations nécessaires à son utilisation. En ce qui concerne la détection de couleur, cette même page propose une méthode très basique consistant à sélectionner la couleur en se basant sur les valeurs brutes. Cependant, cette technique ne fonctionne pas dans la plupart des cas car les valeurs dépendent de nombreux paramètres tels que la luminosité, les nuances de couleur, voire même la présence éventuelle de saleté sur la surface colorée en question. Nous recherchons une solution plus efficace que celle-ci.

Voici le montage à réaliser, directement disponible sur la page du fabricant : Montage capteur APDS 9250

Petite parenthèse, en fonction de vos objectifs, l’utilisation simultanée des deux capteurs peut se révéler être une excellente idée. Cela permet de croiser les prédictions pour obtenir un résultat plus fiable. Par exemple, vous pouvez vérifier les résultats des deux capteurs en comparant la couleur finale trouvée. La complication avec l’utilisation de deux capteurs est qu’il faudra effectuer la procédure de détection de couleur avec les deux capteurs et donc adapter cette méthode à chaque capteur. Cela permet de repérer immédiatement tout problème sur l’un des capteurs ou sur la méthode de détection de couleur.

Jeu de données

Une des solutions possibles consiste à utiliser une intelligence artificielle (IA) afin d’obtenir des résultats plus précis et fiables. Nous allons nous concentrer sur cette approche. Pour commencer, nous aurons besoin d’un jeu de données qui nous permettra d’entraîner notre IA.

Avec le code actuel des capteurs, la valeur RGB des couleurs est affichée en boucle sur la sortie série de l’Arduino. Pour la récupérer, je vous conseille de créer un script Python pour lire les données série et les organiser dans des tableurs. Vous devrez être attentif au format d’écriture sur la liaison série et l’adapter dans le script Python pour qu’il corresponde. Voici un exemple de modèle de script Python pour vous donner une idée :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# installer package serial : pip install pyserial
import serial
import csv

# adaptez le port et le baud rate si besoin
serial = serial.Serial('/dev/ttyUSB0', 115200, timeout=4000)
i = 0
Label = "Blue" # à modifier en fonction de la couleur enregistrée
NbDataToGet = 5 # à modifier en fonction du nombre de données à enregistrer
column_list = ["Red", "Green", "Blue"]
while(i<NbDataToGet) :
    i = i+1
    Red = serial.readline()
    Red = Red.decode('utf-8')

	... # récupérer les valeurs bleu et verte comme le rouge

	# le format d'enregistrement des fichiers est d'un .csv pour chaque couleur
	fileName = open('%s.csv' %Label, 'a')
    writer = csv.DictWriter(fileName, fieldnames=column_list)
    writer = csv.writer(fileName, delimiter=',', quoting=csv.QUOTE_MINIMAL, lineterminator = '\n')
   	writer.writerow([Red, Green, Blue])
    fileName.close()

IA

Une fois que le jeu de données est constitué, nous pouvons l’utiliser pour entraîner l’IA. Le temps d’entrainement va varier en fonction du nombre de couleurs que vous voulez détecter. La durée va augmenter de façon exponentielle plus il y a de couleurs. Nous allons utiliser le modèle SVM (Machine à Vecteurs de Support). Pour faire simple, il s’agit d’un modèle qui excelle dans la classification et de la détection d’anomalie. Si vous voulez en apprendre plus sur ce modèle, je vous conseille d’aller voir cet article.

Ensuite, nous utilisons un second script Python pour générer le fichier .h que nous téléverserons sur l’Arduino. Ce dernier n’est pas très volumineux (environ 6 Kio) ce qui fait que cette approche n’est pas beaucoup plus coûteuse que l’approche normale. Voici ce script :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# installer package sklearn : pip install scikit-learn
from sklearn.datasets import *
from sklearn import neighbors, datasets
from sklearn.svm import SVM
# installer package micromlgen : pip install micromlgen
from micromlgen import port # utilisé pour exporter les modèles sklearn en C

import numpy as np
from glob import glob
from os.path import basename

filepath = '...' # nom du dossier contenant les .csv

def load_features(folder):
	dataset = None
	classmap = {}
	print("Loading features...")
	for class_idx, filename in enumerate(glob('%s/*.csv' % folder)):
    	class_name = basename(filename)[:-4]
    	classmap[class_idx] = class_name
    	print("Reading " + filename + "...")
    	samples = np.loadtxt(filename, dtype=float, delimiter=',')
    	labels = np.ones((len(samples), 1)) * class_idx
    	samples = np.hstack((samples, labels))
    	dataset = samples if dataset is None else np.vstack((dataset, samples))
	return dataset, classmap

# création du modèle SVM
features, classmap = load_features(filepath)
print("Setting in/out...")
X, y = features[:, :-1], features[:, -1]
print("Creating classifier...")
classifier = SVM(kernel='linear', gamma=0.001).fit(X,y)
print("Generating SVM C code...")
c_code = port(classifier, classmap=classmap)
print(c_code)
print("Writing in file...")
file = open('modelSVM.h', "w")
file.write(c_code)
file.close()

Il n’est pas nécessaire de comprendre ce que ce code fait en détail, disons simplement qu’il représente l’IA. En lui fournissant le jeu de données en entrée, il génère en sortie un fichier qui sera capable de détecter avec précision les différentes couleurs. Le package sklearn est utilisé en python pour de la prédiction et l’analyse de données. Nous allons importer le module sklearn.svm qui inclus des algorithmes nous permettant de représenter le modèle SVM. On utilise également quelques modules basiques de sklearn comme sklearn.datasets.

Une fois qu’on a le fichier .h, on peut l’ajouter à notre code arduino et l’utiliser directement :

1
2
3
4
5
6
7
8
#include "modelSVM.h"

Eloquent::ML::Port::SVM clf; // représente le modèle SVM, donc l'IA

...

float values[] = {r, g ,b,}; // récuperer la valeur RGB
String answer = clf.predictLabel(values); // résultat de la couleur prédite

Ce résultat, contrairement à l’approche de base, va nous permettre d’éviter de nombreux faux positifs, tout en augmentant le nombre de couleurs que l’on peut utiliser. En effet, dans l’approche de base, on ne peut détecter que 3 couleurs, alors qu’avec le modèle SVM, j’obtiens des résultats avec un taux de réussite supérieur à 95%, en utilisant jusqu’à 9 couleurs. Si l’on avait ajouté des couleurs à l’approche de base, des conflits seraient survenus entre les conditions pour séparer les couleurs. De plus, il aurait fallu coder en dur toutes les valeurs, ce qui n’est jamais une bonne pratique. Dans le cas où l’on souhaite détecter uniquement les couleurs que l’on a utilisées pour l’entraînement, il est assez facile d’obtenir un taux de réussite de 100% dans la détection.

Conclusion

Pour récapituler, dans ce tutoriel, nous avons appris comment détecter avec précision une couleur en utilisant une Arduino et un capteur couleur classique, en passant par une IA. Cette approche est simple et offre des résultats remarquablement précis dans de nombreuses situations. En fonction de la situation, il est possible qu’un autre modèle d’IA corresponde mieux à vos attentes. Vous pouvez toujours vous renseignez sur ces modèles pour pouvoir les comparer et obtenir les meilleurs résultats possibles.

Annexes

Source de l’image : https://www.artekit.eu/doc/guides/ak-apds-9250/

Projet Gitlab : https://gitlab.cri.epita.fr/lucas.visser/detecter-une-couleur-avec-arduino avec les exemples de code.

Modèle SVM : https://zestedesavoir.com/tutoriels/1760/un-peu-de-machine-learning-avec-les-svm/