Bonjour,
Je travaille actuellement sur la reconnaissance d'un objet par sélection de couleur via openCV et visual studio 2012. Je rencontre un problème lorsque je souhaite sélectionner la couleur en cliquant sur la vidéo en cours.
Voici mon programme main:
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
 
int main(int argc, char **argv)
{
	 IplImage *hsv;
 
	char key;
 
 
 
	// Create the windows
   	cvNamedWindow("GeckoGeek Color Tracking", CV_WINDOW_AUTOSIZE);
   	cvNamedWindow("GeckoGeek Mask", CV_WINDOW_AUTOSIZE);
	cvMoveWindow("GeckoGeek Color Tracking", 0, 100);
	cvMoveWindow("GeckoGeek Mask", 650, 100);
 
 
    while(true){ 
 
 IplImage *image= ardrone.getImage();  //capture l'image
 CvPoint objectNextPos;
 int nbPixels;
 char key;
 
		// If there is no image, we exit the loop
		if(!image)
			continue;
	cvSetMouseCallback("GeckoGeek Color Tracking", getObjectColor);
       key = cvWaitKey(10);
		objectNextPos = binarisation(image, &nbPixels);
		addObjectToVideo(image, objectNextPos, nbPixels);
 
		//We wait 10 ms
		key;
 
	}
 
	// Destroy the windows we have created
	cvDestroyWindow("GeckoGeek Color Tracking");
	cvDestroyWindow("GeckoGeek Mask");
 
 }
 
 
 
    return 0;
}
Voici le détail des fonctions utilisées ici:
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
 
IplImage *image;
 
// Position of the object we overlay
CvPoint objectPos = cvPoint(-1, -1);
// Color tracked and our tolerance towards it
int h = 30, s = 150, v = 255, tolerance = 10;
CvPoint binarisation(IplImage* image, int *nbPixels) {
 
	int x, y;
	CvScalar pixel;
	IplImage *hsv, *mask;
	IplConvKernel *kernel;
	int sommeX = 0, sommeY = 0;
	*nbPixels = 0;
 
	// Create the mask &initialize it to white (no color detected)
	mask = cvCreateImage(cvGetSize(image), image->depth, 1);
 
	// Create the hsv image
	hsv = cvCloneImage(image);
	cvCvtColor(image, hsv, CV_BGR2HSV);
 
	// We create the mask
	cvInRangeS(hsv, cvScalar(h - tolerance -1, s - tolerance, 0), cvScalar(h + tolerance -1, s + tolerance, 255), mask);
	//cvInRangeS(hsv, cvScalar(5, 100, 255), cvScalar(15, 200, 255), mask);
 
	// Create kernels for the morphological operation
	kernel = cvCreateStructuringElementEx(5, 5, 2, 2, CV_SHAPE_ELLIPSE);
 
	// Morphological opening (inverse because we have white pixels on black background)
	cvDilate(mask, mask, kernel, 1);
	cvErode(mask, mask, kernel, 1);  
 
	// We go through the mask to look for the tracked object and get its gravity center
	for(x = 0; x < mask->width; x++) {
		for(y = 0; y < mask->height; y++) { 
 
			// If its a tracked pixel, count it to the center of gravity's calcul
			if(((uchar *)(mask->imageData + y*mask->widthStep))[x] == 255) {
				sommeX += x;
				sommeY += y;
				(*nbPixels)++;
			}
		}
	}
 
	// Show the result of the mask image
	cvShowImage("GeckoGeek Mask", mask);
 
	// We release the memory of kernels
	cvReleaseStructuringElement(&kernel);
 
	// We release the memory of the mask
	cvReleaseImage(&mask);
	// We release the memory of the hsv image
    	cvReleaseImage(&hsv);
 
	// If there is no pixel, we return a center outside the image, else we return the center of gravity
	if(*nbPixels > 0)
		return cvPoint((int)(sommeX / (*nbPixels)), (int)(sommeY / (*nbPixels)));
	else
		return cvPoint(-1, -1);
}
 
void addObjectToVideo(IplImage* image, CvPoint objectNextPos, int nbPixels) {
 
	int objectNextStepX, objectNextStepY;
    CvPoint objectPos = cvPoint(-1, -1) ;
	// Calculate circle next position (if there is enough pixels)
	if (nbPixels > 10) {
 
		// Reset position if no pixel were found
		if (objectPos.x == -1 || objectPos.y == -1) {
			objectPos.x = objectNextPos.x;
			objectPos.y = objectNextPos.y;
		}
 
		// Move step by step the object position to the desired position
		if (abs(objectPos.x - objectNextPos.x) > STEP_MIN) {
			objectNextStepX = max(STEP_MIN, min(STEP_MAX, abs(objectPos.x - objectNextPos.x) / 2));
			objectPos.x += (-1) * sign(objectPos.x - objectNextPos.x) * objectNextStepX;
		}
		if (abs(objectPos.y - objectNextPos.y) > STEP_MIN) {
			objectNextStepY = max(STEP_MIN, min(STEP_MAX, abs(objectPos.y - objectNextPos.y) / 2));
			objectPos.y += (-1) * sign(objectPos.y - objectNextPos.y) * objectNextStepY;
		}
 
	// -1 = object isn't within the camera range
	} else {
 
		objectPos.x = -1;
		objectPos.y = -1;
 
	}
 
	// Draw an object (circle) centered on the calculated center of gravity
	if (nbPixels > 10)
		cvDrawCircle(image, objectPos, 15, CV_RGB(255, 0, 0), -1);
 
	// We show the image on the window
	cvShowImage("GeckoGeek Color Tracking", image);
 
}
 
void getObjectColor(int event, int x, int y, int flags, void *param) {
 
	// Vars
	CvScalar pixel;
	IplImage* hsv= NULL; 
 
 
	if(event == CV_EVENT_LBUTTONUP)	{
 
		//Get the hsv image
		//hsv = cvCloneImage(image);
		//cvCvtColor(image, hsv, CV_BGR2HSV);
 
		// Get the selected pixel
		pixel = cvGet2D(hsv, y, x);
 
		// Change the value of the tracked color with the color of the selected pixel
		h = (int)pixel.val[0];
		s = (int)pixel.val[1];
		v = (int)pixel.val[2];
 
		// Release the memory of the hsv image
    		cvReleaseImage(&hsv);
 
	}
 
}
Les images s'affichent correctement sans problèmes mais lorsque je clic sur l'image pour avoir les pixels voulues le programme plante et me dit cela:

Unhandled exception at at 0x75A6812F in test.exe: Microsoft C++ exception: cv::Exception at memory location 0x003FEED4.

Je peux faire une impression écran pour plus de détails.
Il semble y avoir un problème de mémoire. Je pense que le programme n'apprécie pas trop de changer les valeurs des pixels en tant réel dans des fonctions en cours d'utilisation. Mais je ne vois pas comment faire. Le programme marche parfaitement si on entre manuellement les valeurs des pixels.

Quelqu'un sait-il résoudre ce genre de problème?

Merci.

Cordialement.

Kévin LELU