IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

OpenCV Discussion :

Problème avec cvSetMouseCallback sur Visual Studio 2012


Sujet :

OpenCV

  1. #1
    Nouveau membre du Club
    Inscrit en
    Mars 2013
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Mars 2013
    Messages : 41
    Points : 27
    Points
    27
    Par défaut Problème avec cvSetMouseCallback sur Visual Studio 2012
    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

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    Le problème est que tu as IplImage* hsv= NULL; qui n'est jamais initialisé. Et donc lorsque tu tentes d'accéder à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pixel = cvGet2D(hsv, y, x);
    c'est normal que ça plante.

    Tu peux utiliser le troisième paramètre de la fonction cvSetMouseCallback() afin de faire passer ton image (déjà convertie dans l'espace HSV histoire de ne pas effectuer cette l'opération de conversion dans cet espace à chaque appui).

  3. #3
    Nouveau membre du Club
    Inscrit en
    Mars 2013
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Mars 2013
    Messages : 41
    Points : 27
    Points
    27
    Par défaut
    Bonjour,
    Merci de répondre à ma question.
    Mais je suis toujours bloqué...
    Je pensais que permettait justement d'initialiser la variable hsv.
    J'ai essayé d'initialiser cette variable on écrivant ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    hsv = cvCreateImage(cvGetSize(image), image->depth, 1);
    mais sans succès.
    Vous dites que je peux l'initialiser avec le troisième paramètre de la fonction cvSetMouseCallback() mais je ne vois pas comment faire.
    J'ai essayé ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cvSetMouseCallback("GeckoGeek Color Tracking", getObjectColor,hsv = cvCloneImage(image));
    mais ça ne fonctionne pas.
    Pouvez-vous m'éclaircir un peu plus sur ce sujet svp?
    Merci.
    Cordialement.
    Kévin LELU

  4. #4
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par klelu Voir le message
    Je pensais que permettait justement d'initialiser la variable hsv.
    Initialiser oui dans un sens... mais pas au point d'aller y chercher par la suite des pixels inexistants (c'est un pointeur NULL !)

    Citation Envoyé par klelu Voir le message
    J'ai essayé d'initialiser cette variable on écrivant ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    hsv = cvCreateImage(cvGetSize(image), image->depth, 1);
    mais sans succès.
    L'espace HSV contient 3 canaux et non 1.
    Cette ligne seule te permet d'allouer l'espace mémoire suffisant pour ton image. Tu pourras accéder aux pixels avec cvGet2D() comme tu le fais, mais ils ont à ce point des valeurs aléatoires.
    Citation Envoyé par klelu Voir le message
    Vous dites que je peux l'initialiser avec le troisième paramètre de la fonction cvSetMouseCallback() mais je ne vois pas comment faire.
    Tu fais simplement passer ton image (ou image déjà convertie dans l'espace HSV) en paramètre.
    Citation Envoyé par klelu Voir le message
    J'ai essayé ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cvSetMouseCallback("GeckoGeek Color Tracking", getObjectColor,hsv = cvCloneImage(image));
    mais ça ne fonctionne pas.
    As-tu changé ta fonction getObjectColor() en conséquence ?

  5. #5
    Nouveau membre du Club
    Inscrit en
    Mars 2013
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Mars 2013
    Messages : 41
    Points : 27
    Points
    27
    Par défaut
    J'ai essayé quelques modifications sans plus de succès malheureusement: j'ai toujours la même erreur.
    Voici mes changements:
    Dans le main j'ai donc écris cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    hsv = cvCreateImage(cvGetSize(image), image->depth, 3);
    		hsv = cvCloneImage(image);
    		cvCvtColor(image, hsv, CV_BGR2HSV);
     
     
    		// Mouse event to select the tracked color on the original image
         	cvSetMouseCallback("GeckoGeek Color Tracking", getObjectColor,hsv);
    		cvReleaseImage(&hsv);
    Et j'ai modifié la fonction getObjectColor() comme cela:
    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
    void getObjectColor(int event, int x, int y, int flags, void*hsv) {
     
    	// Vars
    	CvScalar pixel;
     
     
     
    	if(event == CV_EVENT_LBUTTONUP)	{
     
     
     
    		// 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];
     
     
     
    	}
     
    }
    Il y a toujours ce problème de mémoire.
    Voyez-vous à quoi peut-être dû ce problème maintenant?
    Merci.
    Cordialement.
    Kévin LELU

  6. #6
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par klelu Voir le message
    Voici mes changements:
    Dans le main j'ai donc écris cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    hsv = cvCreateImage(cvGetSize(image), image->depth, 3);
    hsv = cvCloneImage(image);
    cvCvtColor(image, hsv, CV_BGR2HSV);
    Là tu as une fuite de mémoire. Supprime ta ligne avec cvCloneImage().

    Citation Envoyé par klelu Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    // Mouse event to select the tracked color on the original image
    cvSetMouseCallback("GeckoGeek Color Tracking", getObjectColor,hsv);
    cvReleaseImage(&hsv);
    Si tu libères la mémoire réservée pour hsv juste après avoir assigné le callback, comment veux-tu que ta fonction getObjectColor() y accède par la suite ?
    Libère cette mémoire lorsque tu ne l'utiliseras vraiment plus

    Citation Envoyé par klelu Voir le message
    Et j'ai modifié la fonction getObjectColor() comme cela:
    C'est bon

  7. #7
    Nouveau membre du Club
    Inscrit en
    Mars 2013
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Mars 2013
    Messages : 41
    Points : 27
    Points
    27
    Par défaut
    Ok c'est bon! Avec les modifications que vous venez de me conseiller ça marche! Merci beaucoup!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème avec CMake et Visual Studio 2008
    Par Darktib dans le forum Visual C++
    Réponses: 2
    Dernier message: 20/07/2011, 11h29
  2. Problème de librairies sur Visual studio 2005 P
    Par QAYS dans le forum VB.NET
    Réponses: 6
    Dernier message: 13/04/2011, 18h06
  3. Réponses: 1
    Dernier message: 14/03/2011, 23h23
  4. problème avec le debogueur visual studio
    Par coquelicot47 dans le forum Visual Studio
    Réponses: 0
    Dernier message: 27/08/2010, 20h30
  5. Problème avec le debugger Visual Studio 2008
    Par Zouch-K dans le forum Visual C++
    Réponses: 2
    Dernier message: 02/04/2010, 14h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo