Seuillage manuel d'une Image
Un article de Wikibot.
[modifier] Le seuillage
Le plus simple pour détecter un objet est, de loin, de regarder si on trouve sa couleur dans l'image.
Pour ce faire, on va fabriquer un buffer de la même taille qu'une image noir et blanc (donc d'une seul des trois matrices composant l'image couleur) dans lequel on va stocker notre information sous forme d'un unsigned char ou d'un unsigned int.
- Un unsigned char sera limité à 7 couleurs de detection, plus le bit de détection d'objet. Il est possible de faire une légère variante si on est limité en mémoire et d'avoir ainsi 127 couleurs reconnaissables, bien plus qu'il n'en faut, et toujours un bit de détection d'objet.
Cette méthode qui n'est pas plus mauvaise, mais empêche d'avoir plusieurs couleur sur le même pixel, ce qui peut être pratique pour avoir certaines informations
- Un unsigned int pourra quand à lui prendre 15 couleurs + 1 bit de detection. Il est aussi possible d'avoir 32768
couleurs + le bit de detection, mais cela provque les mêmes désavantages que précédemment et seuiller autant de couleurs paraît vraiment inutile.
Je tiens a signaler ici que ma méthode est toute personnelle et qu'il y a plein d'autres moyens, mais celui-ci est parmi les plus simples (enfin je pense, sinon je ne l'utiliserais pas!).
Le principe va donc être de regarder quelles sont les valeurs des pixels dans les 3 matrices de couleur dont on dispose (que ce soit en YUV ou en RVB). On va donc parcourir à l'aide d'une (et oui, une seule suffit) boucle FOR la totalité des pixels de chaque matrice
[modifier] Exemple
Ici un petit exemple de 2 possibilites de seuillage manuel:
#define LARGEUR 320 #define HAUTEUR 240 //la taille d'une matrice de pixels #define TAILLE_MATRICE LARGEUR*HAUTEUR #define TAILLE_BUFFER 3*TAILLE_MATRICE //on definit les valeurs des couleurs dans la matrice de seuillage #define NOIR 0x0000 #define ROUGE 0x0001 #define VERT 0x0002 #define BLEU 0x0004 #define BLANC 0x0008 //on defini les seuils //(PRECISION ces valeurs n'ont rien a voir avec la realité) #define SEUIL_Y_ROUGE 20 #define DELTA_Y_U_VERT 15 //Rq: ces valeurs sont faîtes pour ne pas se "recouvrir" //Si on bosse avec une webcam donnant du RGB ou YUV //(ou en YCbCr) 4:4:4 //int mat_pixel[3*TAILLE_MATRICE]; //Sinon avec du YUV (ou enYCbCr) 4:2:2 comme en donne la Philips int mat_pixels[1*TAILLE_MATRICE+2*TAILLE_MATRICE/4]; //un raccourci permettant d'acceder à chacune des matrices simplement: int* mat_pix1=mat_pixels; int* mat_pix2=mat_pixels+TAILLE_MATRICE; //pour la philips int* mat_pix3=mat_pixels+TAILLE_MATRICE+TAILLE_MATRICE/4; //sinon en RGB: //int* mat_pix3=mat_pixels+2*TAILLE_MATRICE; int buffer[TAILLE_MATRICE]; int i;
...
for(i=0;i<TAILLE_MATRICE;i++)
{
buffer[i]=NOIR;
//exemple de seuillage sur une matrice
if(mat_pix1[i]>SEUIL_Y_ROUGE)
buffer[i]=ROUGE;
//Rq: on peut mettre un |= pour garder la couleur qu'on
//avait stockee avant le rouge dans le buffer
//autre type de seuillage: on regarde la différence
//entre 2 matrices (permet d'être moins sensible a la
//luminosité de l'objet)
else if(mat_pix1[i]-mat_pîx2[i/4]<DELTA_Y_U_VERT)
//i/4 car YUV 4:2:2 a plan separes,
//sinon on garderai simplement i
buffer[i]=VERT;
}
Bon, on décode: on passe tous les pixels d'une image en faisant des tests sur les divers matrices composant l'image.
- 1er test: une matrice par rapport a une valeur fixe: permet de faire un test de lunminosité en général
- 2eme test: la différence de 2 matrices par rapport a un delta maxi ou mini: permet de degager assez bien une couleur par rapport aux autres.
Cette année mes tests utilisaient une combinaison de ces 2 systèmes.
Voilà ! Grâce à ça, on a déja recueilli dans notre buffer une version ultra simplifiée de l'image: on détecte les choses noires, les rouges et les vertes, voire meme les blanches
Le résultat de cette méthode sur un de mes premiers screenshots l'utilisant:





