I. Introduction▲
Quel intérêt pédagogique peut-il y avoir à utiliser le champ Webcam ? En fait, ce support va montrer à travers un exemple ludique l'utilisation d'une Webcam pour faire de la détection d'état.
À travers cet exemple, plusieurs thèmes vont être abordés : la création de fichiers image, l'utilisation de fonctions de dessins, l'utilisation du RVB, la création de fichiers de configuration.
Cet applicatif va être utile pour savoir si une zone de couleur définie est présente. Les usages détournés peuvent être :
- la détection de mouvement ;
- vérifier si un bouchon est présent sur une ligne d'embouteillage ;
- etc.
Pour réaliser cet exemple, l'utilisation de la méthodologie objet aurait pu être envisagé, j'ai préféré revenir sur le procédural. Le lecteur motivé pourra regrouper les procédures dans des classes s'il le désire à titre d'approfondissement.
Ce projet se nommera Webcam, et n'aura pas d'analyse. Il y aura deux fenêtres :
- Départ (la fenêtre initiale de l'application) ;
- Param ( la fenêtre de paramétrage).
Le but de cette application est de faire prendre à la webcam un cliché initial qui servira d'étalon, de sélectionner sur l'étalon la zone dont on va ensuite tester la présence.
II. Les écrans ▲
II-A. Voici la première fenêtre nommée départ▲
À droite la zone de la webcam, à gauche le cliché.
II-B. Voici le second écran nommé param▲
III. La conception▲
III-A. Voici l'écran « Départ » en mode conception ▲
La fenêtre a comme dimension : 676x410.
Pour connaître ou modifier les dimensions données ici, regardez en bas à droite de l'éditeur WinDev :
On trouve comme info :
le nom de la fenêtre ;
la position relative de l'objet dans la fenêtre ;
la taille de l'objet ;
le plan dans lequel il se trouve.
Pour changer les dimensions, vous pouvez modifier directement les valeurs. Commencer par modifier les valeurs de la fenêtre départ
Si vous voulez réécrire la taille le signe de la multiplication est la lettre X et non l'étoile de la multiplication. |
Voici les caractéristiques de tous les objets :
Type de champ |
Nom |
Libelle |
Position relative |
Taille |
Libelle |
Par défaut |
Source |
6,6 |
324X309 |
Libelle |
Par défaut |
Capture |
336,6 |
324X309 |
Champ de saisie |
EtatObjet |
Aucun |
209,336 |
250X26 |
Champ Créer une image |
Source |
Aucun |
12,26 |
310X242 |
Champ Web Caméra |
Capture |
Aucun |
343,26 |
310X242 |
Bouton |
Bparam |
Paramétrage |
13,284 |
80X24 |
Bouton |
Bcapture |
Capture |
243,284 |
80X24 |
Bouton |
Btest |
Test |
448,284 |
80X24 |
Champ Créer une image |
Cible |
Aucun |
691,-13 |
310X242 |
Placez les objets et normalement si vous respectez les consignes votre fenêtre ressemblera à celle représentée en haut de cette page.
Le champ webcam doit être « branché » sur votre Webcam, vous allez le faire manuellement en cliquant avec le bouton droit sur le champ. Choisissez description puis dans l'onglet général, faites apparaître votre Webcam dans la combo « Webcam utilisée »
Maintenant, voyons le code de cet écran.
Lorsque l'application se lance s'il y a déjà eu une image « étalon » nous allons faire en sorte qu'elle s'affiche dans sa zone image.
Dans la zone de code d'initialisation de la fenêtre départ saisissez ceci :
source
=
"etalon.jpeg"
Voici le code du bouton Bcapture :
dSauveImageJPEG
(
capture,
"etalon.jpeg"
)
source
=
""
source
=
"etalon.jpeg"
La fonction dSauveImageJpeg gele le contenu du champ Webcam « capture » et l'enregistre sous « etalon.jpeg ».
L'instruction suivante enlève le contenu du champ image « source ».
L'instruction d'après met l'image « etalon.jpeg » dans le champ « source ».
Voici le code du bouton Btest :
dSauveImageJPEG
(
capture,
"test.jpeg"
)
cible=
""
cible=
"test.jpeg"
Compare
Vous avez surement vu que je vous ai fait placer une zone image hors fenêtre ? Ce champ image va nous servir au test de comparaison.
Donc, le code du bouton Btest fait prendre un cliché appelé « test.jpeg », l'affecte au champ image « cible » et lance la procédure de comparaison.
Voyons de suite le contenu de cette procédure compare. Créez une procédure locale nommée compare dont voici le code :
J'en vois qui, rien qu'a la lecture de ce code, claquent des dents, il y en même qui s'évanouissent !
Je vous rappelle le principe du programme.
La fenêtre « param » va vous permettre de sélectionner une zone rectangulaire de test, nous aurons donc quatre points (X1,X2,Y1,Y2)
Comme nous ferons des recherches sur les couleurs il faut pouvoir donner un pourcentage (c'est grâce au champ potentiomètre de la fenêtre « param » ) de spectre rouge acceptable, idem pour le vert et le bleu. C'est pour cette raison que vous verrez des limites bleu-, bleu+, etc.
Voyons les variables.
Resultante est un entier qui contiendra le code couleur d'un pixel situé à un point (x,y) de la zone image cible et qui servira pour le test de comparaison avec l'image étalon.
X1,X2,Y1,Y2 sont des entiers qui contiennent les points définissant la zone rectangulaire.
Letableau est un tableau qui contient les limites couleur RVB.
Trouve est un booléen qui nous indiquera si les couleurs recherchées sont toutes trouvées.
On va placer dans les variables X1,X2,Y1,Y2 les points définissant notre zone rectangulaire de test. Ces points sont dans un fichier Ini nommé ParametresW.ini.
Pour avoir une idée du fonctionnement de INITLit ouvrez l'aide.
Le tableau va être rempli avec les valeurs couleur limites.
TANTQUE
x1<
x2
resultante=
dPixelCouleur
(
cible,
x1,
y1)
trouve=
Spectre(
resultante,
letableau)
x1+=
1
y1+=
1
FIN
Les plus rapides ont-ils compris ce que fait ce code ? Pour les autres voici une explication. En fait, on va tracer une diagonale dans notre zone rectangulaire, point par point. Pour chaque point on relève sa couleur dans la variable résultante. Cette variable résultante est passée dans la procédure globale Spectre qui contrôle si la couleur est comprise dans les limites RVB de références.
Selon le résultat du booléen trouve, on affiche un message dans la zone EtatObjet.
Voici le code de la procédure globale « Spectre » :
Explication du code
Pour trouver la valeur RGB comprise dans l'entier renvoyé par la fonction DpixelCouleur on est obligé d'effectuer certains calculs.
Ainsi pour avoir la dominante Rouge on effectue le calcul suivant l'entier couleur modulo 256.
Dans le tableau nous avons nos limites par couleur. Le but est de voir si la couleur récupérée est comprise entre ces deux valeurs du tableau.
Nous avons un booléen qui selon son état indiquera si la couleur est dans les limites.
Vous aurez une vue d'ensemble lorsque la fenêtre param aura été vue.
Voyons le code du bouton Bparam :
Ouvre
(
Param)
III-B. Maintenant que tout le code de la fenêtre départ est décrit passons à la fenêtre Param▲
La fenêtre a les dimensions suivantes : 660X320
Voici le tableau de positionnement :
Type de champ |
Nom |
Libelle |
Position relative |
Taille |
Champ image |
Mire |
Source |
5,5 |
310X242 |
Bouton |
Selection |
Capture |
336,6 |
324X309 |
Bouton |
Enregistre |
Enregistrer les variables d'étalonnages |
365,161 |
219X24 |
Potentiomètre |
Par défaut |
335,26 |
290X38 |
|
Libelle |
Par défaut |
Potentiomètre d'imprécision |
328,6 |
304X66 |
Champ de saisie |
Nomdezone |
Nom de la zone sélectionnée : |
328,78 |
297X22 |
Vous devez avoir maintenant une fenêtre ressemblante à celle présentée ci-dessus.
Dans la zone de déclaration globale de la fenêtre, inscrivez ceci :
rescouleur,
Crouge,
Cvert,
Cbleu sont
des
entiers
Lex,
ley sont
des
entiers
letab est
un
tableau
de
6
entiers
Le potentiomètre va nous servir pour avoir un pourcentage dans la couleur sélectionnée. Par exemple, si l'utilisateur a cliqué dans un rouge de code RVB 200 et que la valeur retournée par le potentiomètre est 10, on appliquera 10 % de plus à 200 pour la couleur la plus haute et -10 % pour avoir l'intervalle bas.
Ces deux valeurs seront ensuite enregistrées dans un tableau.
Voici le descriptif du potentiomètre.
Faites un clic droit dessus et choisissez « Description » ensuite l'onglet « Détail ». Dans la zone valeur initiale mettez 10, dans la valeur minimale mettez 0 et 100 pour la maximale.
Voici le code du bouton sélection :
Mire..
CurseurSouris
=
curCroix
Comme vous le voyez, ce code ne fait pas grand-chose, il fait en sorte que le curseur de survol de l'image soit une croix.
Voyons maintenant comment s'opère la sélection d'une zone couleur. Pour pouvoir capturer une zone, il faut que l'utilisateur clique dans l'image. Le code sera donc dans la partie clic de la zone image. Le voici :
Il faut donc qu'à chaque clic le système nous délimite une zone couleur sur l'image étalon, pour éviter de superposer les rectangles de sélection à chaque clic l'image de base est réécrite dans la zone image.
C'est le rôle de la première ligne.
Ensuite nous récupérons la position exacte de la souris lors du clic.
Puis nous récupérons la valeur couleur du pixel situé à la position de la souris.
Nous calculons les Valeurs RVB.
Il nous faut ensuite remplir le tableau des valeurs couleur du point cliqué. C'est la fonction Spectre_origine qui s'en charge.
Voici son code :
Ce code ne sert qu'à remplir un tableau de valeurs correspondantes à un entier sur lequel on applique un pourcentage donné par le potentiomètre.
Voyons maintenant la fonction CalculZone.
PROCEDURE
calculzone(
posx,
posy,
letableau)
Pxd,
pxg,
pyb,
pyh sont
des
entiers
trouve est
un
booléen
=
Vrai
Pxd=
posx
pxg=
posx
pyb=
posy
pyh=
posy
dDébutDessin
(
Mire)
// on recherche une zone rectangulaire comportant cette couleur
// on commence par les x vers la droite
TANTQUE
trouve
SI
Spectre(
dPixelCouleur
(
Mire,
Pxd,
posy),
letableau)
ALORS
Pxd=
Pxd+
1
SINON
trouve=
Faux
FIN
FIN
// on continue les x vers la gauche
trouve=
Vrai
TANTQUE
trouve
SI
Spectre(
dPixelCouleur
(
Mire,
pxg,
posy),
letableau)
ALORS
pxg=
pxg-
1
SINON
trouve=
Faux
FIN
FIN
// on cherche y vers le bas
trouve=
Vrai
TANTQUE
trouve
SI
Spectre(
dPixelCouleur
(
Mire,
posx,
pyb),
letableau)
ALORS
pyb=
pyb+
1
SINON
trouve=
Faux
FIN
FIN
// on cherche y vers le haut
trouve=
Vrai
TANTQUE
trouve
SI
Spectre(
dPixelCouleur
(
Mire,
posx,
pyh),
letableau)
ALORS
pyh=
pyh-
1
SINON
trouve=
Faux
FIN
FIN
INIEcrit
(
"Points"
,
"X1"
,
NumériqueVersChaîne
(
pxg),
fRepEnCours
()+
"\ParametresW.ini"
)
INIEcrit
(
"Points"
,
"Y1"
,
NumériqueVersChaîne
(
pyh),
fRepEnCours
()+
"\ParametresW.ini"
)
INIEcrit
(
"Points"
,
"X2"
,
NumériqueVersChaîne
(
Pxd),
fRepEnCours
()+
"\ParametresW.ini"
)
INIEcrit
(
"Points"
,
"Y2"
,
NumériqueVersChaîne
(
pyb),
fRepEnCours
()+
"\ParametresW.ini"
)
dRectangle
(
pxg,
pyh,
Pxd,
pyb,
iTransparent
,
iNoir
)
Cette fonction a un rôle important. Lorsque l'on clique sur l'image elle va essayer de trouver une zone rectangulaire comprise dans un spectre, plus ou moins le pourcentage, défini par la couleur de référence du clic. Une fois la zone couleur définie, les valeurs des points ayant servi à faire la zone rectangulaire sont mémorisées dans le fichier ini.
Maintenant voici le code du bouton enregistre :
Ce code ne fait qu'enregistrer les variables dans un fichier ini qui sera utilisé dans le code de la fenêtre départ pour interpréter l'image.
Voilà le code est saisi, vous pouvez essayer votre application.