Bonjour à tous,
Je vais essayer d’expliquer mon problème le plus facilement possible. Dans le cadre d'un projet je suis en train de développer un programme de reconnaissance et d’apprentissage du langage des signes, ou du moins on essaye .

Perso je m'occupe d'une partie qui permet à l'utilisateur de choisir un signe sur lequel il pourra s'exercer. Lorsqu'il choisit le signe son contour s'affiche en transparence sur la vidéo et il doit faire en sorte de bien positionner sa main de telle façon à bien coller avec ce contour.

Si ça colle la couleur du contour, initialement rouge, passe en vert. Mon problème survient à ce moment.

L'image source est la suivante : http://img11.hostingpics.net/pics/693857tpl.jpg
Lors du changement de couleur des pixels blancs en pixels rouge ou vert et de la suppression du fond noir pour l'affichage en transparence. Je vois apparaître une sorte de bruit en arrière plan et je n'arrive pas à comprendre d'où cela peut venir.

J'ai testé mes fonctions de masque et de changement de couleur à part et cela marche très bien ...

Donc merci à vous si vous pouvez m'aider où même trouver un autre moyen, je reste ouvert

Je vous poste mon code simplifié (pour l'image main voici le lien http://img11.hostingpics.net/pics/246723main.jpg et pour l'image tpl c'est le lien précédent) .

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/* 
Partie apprentissage :
mise à part le seuillage qui reste à determiner il faut regler le probleme du 
switch des couleur avec l'apparition d'une sorte de bruit dans le rectangle.
 
Pour compiler : 
g++ test.cpp -lopencv_core -lopencv_highgui -lopencv_imgproc -o test
*/
#include "opencv/highgui.h"
#include "opencv/cv.h"
#include <iostream>
 
using namespace cv;
using namespace std;
 
/** \brief createMask
 * Fonction qui créee un masque pour pouvoir afficher le 
 * contour en transparence sur la vidéo
 * @param image image source
 * @return mask image résultat
 */
IplImage* createMask(IplImage* image) {
	IplImage *mask;
	mask = cvCreateImage(cvGetSize(image), 8, 1);
	//si pixels compris entre la couleur 0,0,0 et 200,200,200 on le remplace par du vide
	cvInRangeS(image, cvScalar(0, 0, 0), cvScalar(200, 200, 200), mask);
	cvNot(mask, mask);
	return mask;
}
 
/** \brief changeColorPixel
 * Fonction qui change la couleur des pixels blancs 
 * @param image image source
 * @param c couleur voulue
 * @return result
 */
IplImage* changeColorPixel(IplImage* image, CvScalar c)
{
  CvScalar pixel;
  IplImage* result;
  result = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,3);
  for(int i=0;i<image->height;i++){
    for(int j=0;j<image->width;j++){
      pixel=cvGet2D(image,i,j);
      //si valeur pixel superieur à 250,250,250 (donc plutot blanc), on remplace
      if(pixel.val[0]>=250 && pixel.val[1]>=250 && pixel.val[2]>=250){
	pixel.val[0]=c.val[0];
	pixel.val[1]=c.val[1];
	pixel.val[2]=c.val[2];
	cvSet2D(result,i,j,pixel);
      }
    }
  }
  return result;
}
 
 
int main() {
 
	IplImage *image, //image de la capture video
		 *source, //image contour bdd
		 *contour, //copie de source pour les changements de couleurs
		 *mask1, // masque que l'on applique sur le contour pour enlever fond noir
		 *imageM, //image du signe a reconnaitre
		 *imageM2, //copie de l'image signe en Gray
		 *tpl; //image template en Gray extraite de la capture video pour comparaison avec le signe
	IplImage* resultat = cvCreateImage(cvSize(1,1), IPL_DEPTH_32F, 1);//image resultat du matchTemplate
	// CApture Video
	CvCapture * capture;
	// key pour les events clavier
	char key;
 	//valeur des seuils pour le matchTemplate, seul min_val est utilisé
	double min_val=1;
	double max_val=1;
	//dimension de la capture video (peut changer selon la webcam)
	int CptWidth = 640;
	int CptHeight = 480;
 
	// Importation des images
	source = cvLoadImage("tpl.jpg"); //contour simple présent dans la bdd
	imageM = cvLoadImage("main.jpg"); //signe de la bdd choisit par l'utilisateur
 
	// Creation des fenetres
   	cvNamedWindow("Mode leçon", CV_WINDOW_AUTOSIZE);
 
	// Initialisation capture video
 	capture = cvCreateCameraCapture(200);
    	if (!capture) {
		printf("Can't initialize the video capture.\n");
        	return -1;
 	}
 	if(!cvGrabFrame( capture ))
		printf("Capture de FRAME impossible !\n");
 
	//transformation de l'image du signe en Gray pour s'affranchir de la contrainte de l'eclairage
	imageM2 = cvCreateImage(cvGetSize(imageM),8,1);
	cvCvtColor( imageM, imageM2, CV_BGR2GRAY );
	cvCanny(imageM2, imageM2, 127,127);
	cvNot(imageM2, imageM2);
	//on selectionne la partie de l'image du signe correspondant au template
 	cvSetImageROI(imageM2, cvRect((CptWidth-source->width)/2,(CptHeight-source->height)/2, source->width, source->height));
 
	while(key != 'Q' && key != 'q') {
 
		// on prend l'image courante puis on l'inverse pour avoir un effet mirroir
		image = cvQueryFrame(capture);
		cvFlip (image, 0, 1);
		// Si pas d'image tu sors !
		if(!image)
			continue;
 
		//transformation du template en Gray pour comparaison avec le signe
		tpl = cvCreateImage (cvGetSize(image),8,1);
		cvCvtColor(image, tpl,CV_BGR2GRAY);
		//on selectionne la partie de la video correspondant au template
		cvSetImageROI(tpl, cvRect((CptWidth-source->width)/2,(CptHeight-source->height)/2, source->width, source->height));
 
		//matchTemplate entre image template et le signe
		//puis récuperation des valeurs min et max
		cvMatchTemplate(tpl,imageM2,resultat, CV_TM_SQDIFF_NORMED);
		cvResetImageROI(tpl);
		cvMinMaxLoc(resultat, &min_val, &max_val);
		//affichage des valeurs dans console
		cout<<"max : "<<max_val<<" min :"<<min_val<<endl;
 
		//preparation du contour pour affichage en transparence sur l'image de la capture video
		 contour = changeColorPixel(source, cvScalar(0,0,255)); // au départ rouge
		 mask1 = createMask(contour); //on enleve le fond noir
		 //on y affiche le rectangle sur image	
		 cvRectangle(image, cvPoint((CptWidth-source->width)/2, (CptHeight-source->height)/2), cvPoint((CptWidth-source->width)/2+source->width, (CptHeight-source->height)/2+source->height), cvScalar(0,0,255));	
		 cvSetImageROI(image, cvRect((CptWidth-source->width)/2,(CptHeight-source->height)/2, source->width, source->height));
		 //on applique le masque
		 cvCopy(contour, image, mask1);
		 cvResetImageROI(image);//on revient à la taille de départ mais maintenant le signe est présent en transparence avec un rectangle autour
 
		 //Si resultat satisfaisant on change la couleur du contour et du rectangle en vert
		 //Seuil à regler
		 if(min_val<=0.2)
		{
		  contour=changeColorPixel(source, cvScalar(0,255,0));//vert
		  mask1 = createMask(contour);
		  cvRectangle(image, cvPoint((CptWidth-source->width)/2, (CptHeight-source->height)/2), cvPoint((CptWidth-source->width)/2+source->width, (CptHeight-source->height)/2+source->height), cvScalar(0,255,0));	
		  cvSetImageROI(image, cvRect((CptWidth-source->width)/2,(CptHeight-source->height)/2, source->width, source->height));
		  cvCopy(contour, image, mask1);
		  cvResetImageROI(image);
		}
		//on affiche 
		cvShowImage("Mode leçon", image);
		//Release des images ne servant plus à la fin de la boucle
		//et surtout EVITE depassement de memoire
		cvReleaseImage(&tpl);
		cvReleaseImage(&mask1);
		cvReleaseImage(&contour);
 
		key = cvWaitKey(10);
	}
 
	// Destroy the window we have created
	cvDestroyAllWindows();
	// Destroy all created images
	cvReleaseImage(&mask1);
	cvReleaseImage(&source);
	cvReleaseImage(&imageM);
	cvReleaseImage(&imageM2);
	cvReleaseImage(&resultat);
	cvReleaseImage(&contour);
	cvReleaseImage(&tpl);
	cvReleaseImage(&image);
	// Destroy the capture
	cvReleaseCapture(&capture);
 
	return 0;
}