2017-05-23 17:15:23 +02:00
/**
* \ file KirbyTrack . c
* \ author Jacques / Antoine
* \ date avril - mai 2017
* \ brief Figure Imposé : Suivi d ' un objet coloré .
*
* \ details Suivie d ' un Kirby ( Rose ) ou d ' une é toile ( Jaune ) par une caméra avec mode interface utilisateur ou configuration
2017-05-23 18:00:19 +02:00
* \ bug SFML ne supporte qu ' un nombre limité de sprite en fonction du PC
* \ bug Affichage OpenCV incompatible avec SFML
* \ todo Optimisation du chargement de la frame en image SFML
2017-05-23 17:15:23 +02:00
*/
2017-05-01 20:45:20 +02:00
# include <stdio.h>
# include <stdlib.h>
# include <cv.h>
# include <highgui.h>
2017-05-02 18:17:11 +02:00
# include <SFML/Audio.hpp>
# include <SFML/Graphics.hpp>
2017-05-16 17:36:09 +02:00
# include <SFML/Window.hpp>
2017-05-23 17:15:23 +02:00
/**
* \ def SFML
* \ brief Programme en mode affichage interface utilisateur
*
* \ def CONFIG
* \ brief Programme en mode configuration couleur
*
* \ def KIRBY
* \ brief Programme en mode suivi de Kirby ( Objet rose )
*
* \ def ETOILE
* \ brief Programme en mide suivi de l ' é toile ( Objet jaune )
*
* \ def JEU
* \ brief Coefficient de tolérance pour le suivi d ' objet
*/
2017-05-09 21:53:20 +02:00
//#define CONFIG
# define SFML
2017-05-02 18:17:11 +02:00
2017-05-03 13:11:28 +02:00
# define KIRBY
//#define ETOILE
2017-05-16 17:36:09 +02:00
# define JEU 0.15
2017-05-02 18:17:11 +02:00
//ATTENTION AFFICHAGE OPENCV INCOMPATIBLE AVEC AFFICHAGE SFML
2017-05-16 17:36:47 +02:00
//ATTENTION SFML SUPPORTE UN NOMBRE LIMITE DE SPRITE EN FCT DU PC
2017-05-01 20:45:20 +02:00
/*Headers*/
2017-05-23 17:15:23 +02:00
/**
* \ fn void maj_angle ( int vecX , int vecY , int rayon , double * angle )
* \ brief Met à jour \ a angle selon la distance entre le centre de la caméra et la cible , avec un tolérance circulaire définie par rayon
* \ author Jacques
* \ param vecX composante X de la cible par rapport au centre de l ' image
* \ param vecY composante Y de la cible par rapport au centre de l ' image
* \ param rayon tolérance avant changement d ' angle
* \ param angle tableau contenant les deux angles à modifier
*/
void maj_angle ( int vecX , int vecY , int rayon , double * angle ) ; //Met à jour l'angle selon la distance CentreCamera - Cible
/**
* \ fn int ajust_pos ( int pos , int ref )
* \ brief permet d ' é viter des positions supérieures à ref considérées comme aberrantes .
* \ details retourne 0 si la position est supérieure à ref .
* \ author Jacques
* \ param pos position à tester
* \ param ref position de référence
* \ return renvoie la position corrigée
*/
int ajust_pos ( int pos , int ref ) ;
/**
* \ fn void controle_moteur ( double * angle )
* \ brief Fonction d ' envoie des angles aux moteurs
* \ details
* \ author Jacques
* \ param angle tableau des angles moteurs
*/
void controle_moteur ( double * angle ) ; //Envoie les angles au moteur
/**
* \ fn int limite_moteur ( int val_pwm )
* \ brief Fonction qui vérifie que les valeurs envoyees aux moteurs sont correctes
* \ details Valeur minimale = 30 , valeur maximale = 130 ( déterminées expérimentalement )
* \ author Jacques
* \ param val_pwm valeur pwm dont on veut vérifier la valeur
* \ return renvoie l ' angle corrigée
*/
2017-05-09 16:29:35 +02:00
int limite_moteur ( int val_pwm ) ; //Verifie que les valeurs envoyees aux moteurs sont correctes
2017-05-03 13:11:28 +02:00
2017-05-23 17:15:23 +02:00
/**
* \ fn void config ( int * LowH , int * HighH , int * LowS , int * HighS , int * LowV , int * HighV )
* \ brief Fonction d ' affichage du panneau de configuration de la \ a couleur à suivre
* \ author Antoine
* \ details Panneau de configuration comprenant 6 slidebarres pour configurer la couleur suivie en HSV . La fonction modifie les valeurs limites LowH /
* HighH de la plage HUE , LowS / HighS de la plage SATURATION , LowV / HighV de la plage VALUE .
* \ param LowH Valeur \ a basse de la plage de HUE suivie .
* \ param HighH Valeur \ a haute de la plage de HUE suivie .
* \ param LowS Valeur \ a basse de la plage de SATURATION suivie .
* \ param HighS Valeur \ a haute de la plage de SATURATION suivie .
* \ param LowV Valeur \ a basse de la plage de VALUE suivie .
* \ param HighV Valeur \ a haute de la plage de VALUE suivie .
*/
2017-05-03 13:11:28 +02:00
void config ( int * LowH , int * HighH , int * LowS , int * HighS , int * LowV , int * HighV ) ; //Affiche le panneau de configuration de tracking avec les arguments comme valeur de base
2017-05-23 17:15:23 +02:00
/**
* \ fn void affichage_config ( IplImage * frame , IplImage * HSV , IplImage * Binaire ) ;
* \ brief Fonction d ' affichage du flux vidéo , du flux en HSV et de sa binarisation
* \ author Antoine
* \ param frame image contenant la frame capturé par la caméra
* \ param HSV image contenant l ' image passé en HSV
* \ param Binaire image contenant l ' image binarisée
*/
2017-05-03 13:11:28 +02:00
void affichage_config ( IplImage * frame , IplImage * HSV , IplImage * Binaire ) ; //Affiche le flux vidéos et ses différent traitements
2017-05-23 17:15:23 +02:00
/**
* \ fn void Affichage_Tracking ( IplImage * frame , int posX , int posY , int width , int height )
* \ brief Fonction d ' affichage des informations de suivi
* \ details Dessine sur \ a frame la zone de tolérance de suivie au centre de l ' image et le curseur de position de l ' objet ayant pour coordonées \ a posX et \ a posY
* \ author Antoine
* \ param frame image a modifier
* \ param posX composante X du curseur a dessiner
* \ param posY composante Y du curseur a dessiner
* \ param width largeur ( en \ a pixel ) de \ a frame
* \ param height hauteur ( en \ a pixel ) de \ a frame
*/
2017-05-03 13:11:28 +02:00
void Affichage_Tracking ( IplImage * frame , int posX , int posY , int width , int height ) ; //Dessine les informations de tracking sur frame
2017-05-23 17:15:23 +02:00
/**
* \ fn void Position_moy ( IplImage * Binaire , int * posX , int * posY )
* \ brief Effectue le baricentre des pixels d ' une image binaire pour obtenir la postion de l ' objet
* \ author Antoine
* \ param Binaire image binarisée ( matrice de 0 ou de 1 )
* \ param posX contient la composante X du barycentre
* \ param posY contient la composante Y du barycentre
*/
2017-05-03 13:11:28 +02:00
void Position_moy ( IplImage * Binaire , int * posX , int * posY ) ; //Effectue le baricentre des pixels d'une image binaire pour obtenir la postion de l'objet
2017-05-23 17:15:23 +02:00
/**
* \ fn void traitement ( IplImage * frame , IplImage * HSV , IplImage * Binaire , int LowH , int HighH , int LowS , int HighS , int LowV , int HighV )
* \ brief Effectue une binarisation de \ a frame en fonction des bornes \ a HSV
* \ details Passe la frame en HSV puis binarise l ' image en fonction des bornes LowH , HighH , LowS , HighS , LowV , HighV
* \ author Antoine
* \ param frame image contenant la frame capturé par la caméra
* \ param HSV image contenant l ' image passé en HSV au terme de la fonction
* \ param Binaire image contenant l ' image binarisée au terme de la fonction
* \ param LowH Valeur \ a basse de la plage de HUE suivie .
* \ param HighH Valeur \ a haute de la plage de HUE suivie .
* \ param LowS Valeur \ a basse de la plage de SATURATION suivie .
* \ param HighS Valeur \ a haute de la plage de SATURATION suivie .
* \ param LowV Valeur \ a basse de la plage de VALUE suivie .
* \ param HighV Valeur \ a haute de la plage de VALUE suivie .
*/
2017-05-03 13:11:28 +02:00
void traitement ( IplImage * frame , IplImage * HSV , IplImage * Binaire , int LowH , int HighH , int LowS , int HighS , int LowV , int HighV ) ; //Effectue une binarisation de frame en fonction des bornes HSV
2017-05-23 17:15:23 +02:00
/**
* \ fn int main ( int argc , char * argv [ ] )
* \ brief Entrée du programme
* \ author Antoine / Jacques
* \ return EXIT_SUCCESS : Arrêt normal du programme , EXIT_FAILURE : Le programme a rencontrée une erreur au cours de son execution
*/
2017-05-01 20:45:20 +02:00
int main ( int argc , char * argv [ ] )
{
2017-05-09 16:29:35 +02:00
//Initialisations
2017-05-16 17:36:09 +02:00
int height , width ; //parameters of the image we are working on
2017-05-01 20:45:20 +02:00
int posX , posY ; //Position objet
2017-05-02 18:17:11 +02:00
int boucle ;
2017-05-09 18:09:07 +02:00
double angle [ 2 ] = { 100 , 100 } ;
2017-05-02 18:17:11 +02:00
2017-05-23 14:30:22 +02:00
int tracking ; //0 = tracking OFF
2017-05-09 21:53:20 +02:00
2017-05-09 16:53:19 +02:00
2017-05-09 16:29:35 +02:00
# ifdef SFML
2017-05-02 18:17:11 +02:00
//Initialisation SFML
2017-05-16 17:36:09 +02:00
2017-05-02 18:17:11 +02:00
sf : : Texture txFlux ;
sf : : Sprite spFlux ;
sf : : Image imFlux ;
2017-05-09 18:01:10 +02:00
sf : : Event event ;
2017-05-09 21:53:20 +02:00
tracking = 0 ; //Pas de tracking de base en mode SFML
2017-05-02 18:17:11 +02:00
# endif
2017-05-09 16:29:35 +02:00
//Ouverture flux camera
CvCapture * capture = cvCaptureFromCAM ( 0 ) ;
2017-05-01 20:45:20 +02:00
2017-05-09 16:29:35 +02:00
if ( ! capture ) {
printf ( " ERROR: capture is NULL \n " ) ;
exit ( EXIT_FAILURE ) ;
}
2017-05-01 20:45:20 +02:00
2017-05-02 18:17:11 +02:00
2017-05-09 16:29:35 +02:00
// grab an image from the capture
IplImage * frame = cvQueryFrame ( capture ) ;
2017-05-01 20:45:20 +02:00
2017-05-09 16:29:35 +02:00
// get the image data
height = frame - > height ;
width = frame - > width ;
2017-05-01 20:45:20 +02:00
// capture size -
CvSize size = cvSize ( width , height ) ;
2017-05-09 16:44:50 +02:00
2017-05-02 18:17:11 +02:00
# ifdef SFML
2017-05-09 16:44:50 +02:00
//Création de la fenetre principale
2017-05-09 18:01:10 +02:00
sf : : RenderWindow window ( sf : : VideoMode ( width + 300 , height ) , " KirbyTrack " ) ;
2017-05-02 18:17:11 +02:00
# endif
2017-05-01 20:45:20 +02:00
// Initialize different images that are going to be used in the program
IplImage * hsv_frame = cvCreateImage ( size , IPL_DEPTH_8U , 3 ) ; // image converted to HSV plane
IplImage * threshold = cvCreateImage ( size , IPL_DEPTH_8U , 1 ) ;
2017-05-09 16:53:19 +02:00
2017-05-01 20:45:20 +02:00
2017-05-09 16:29:35 +02:00
//Controle couleur
2017-05-03 13:11:28 +02:00
# ifdef KIRBY
2017-05-01 20:45:20 +02:00
//Setup Kirby
2017-05-09 18:09:07 +02:00
int iLowH = 152 ;
2017-05-09 16:29:35 +02:00
int iHighH = 179 ;
2017-05-01 20:45:20 +02:00
2017-05-09 16:29:35 +02:00
int iLowS = 48 ;
int iHighS = 255 ;
2017-05-01 20:45:20 +02:00
2017-05-09 16:29:35 +02:00
int iLowV = 101 ;
int iHighV = 255 ;
2017-05-03 13:11:28 +02:00
# endif
# ifdef ETOILE
//Setup Etoile
int iLowH = 20 ;
int iHighH = 30 ;
2017-05-01 20:45:20 +02:00
2017-05-03 13:11:28 +02:00
int iLowS = 100 ;
int iHighS = 255 ;
2017-05-01 20:45:20 +02:00
2017-05-03 13:11:28 +02:00
int iLowV = 100 ;
int iHighV = 255 ;
# endif
2017-05-01 20:45:20 +02:00
2017-05-03 13:11:28 +02:00
# ifdef CONFIG
//Affichage du panneau de config
config ( & iLowH , & iHighH , & iLowS , & iHighS , & iLowV , & iHighV ) ;
2017-05-01 20:45:20 +02:00
2017-05-02 18:17:11 +02:00
boucle = 1 ;
2017-05-09 21:53:20 +02:00
tracking = 1 ; //Tracking de base en mode CONFIG
2017-05-02 18:17:11 +02:00
# endif
2017-05-09 16:44:50 +02:00
while ( boucle )
2017-05-09 16:53:19 +02:00
{
2017-05-02 18:17:11 +02:00
# ifdef SFML
2017-05-09 16:29:35 +02:00
boucle = window . isOpen ( ) ;
// on inspecte tous les évènements de la fenêtre qui ont été émis depuis la précédente itération
while ( window . pollEvent ( event ) )
{
// évènement "fermeture demandée" : on ferme la fenêtre
if ( event . type = = sf : : Event : : Closed )
window . close ( ) ;
}
2017-05-02 18:17:11 +02:00
# endif
2017-05-01 20:45:20 +02:00
2017-05-09 16:29:35 +02:00
// Get one frame
frame = cvQueryFrame ( capture ) ;
if ( ! frame ) {
perror ( " ERROR: frame is null... " ) ;
break ;
}
2017-05-01 20:45:20 +02:00
2017-05-09 16:29:35 +02:00
//Binarisation du flux vidéo
traitement ( frame , hsv_frame , threshold , iLowH , iHighH , iLowS , iHighS , iLowV , iHighV ) ;
// Calculate the moments to estimate the position of the ball
Position_moy ( threshold , & posX , & posY ) ;
//Dessine les informations de tracking sur frame
Affichage_Tracking ( frame , posX , posY , width , height ) ;
2017-05-02 18:17:11 +02:00
2017-05-09 16:44:50 +02:00
2017-05-02 18:17:11 +02:00
# ifdef SFML
2017-05-23 14:30:22 +02:00
//Affichage SFML
2017-05-02 18:17:11 +02:00
/* Clear the screen */
2017-05-09 18:01:10 +02:00
window . clear ( sf : : Color : : White ) ;
2017-05-02 18:17:11 +02:00
2017-05-23 14:30:22 +02:00
//Affichage de la frame
//Le chargement pourrait etre plus optimisé en créant nous me l'image SFML en parcourant l'IplImage
2017-05-09 21:53:20 +02:00
2017-05-09 16:44:50 +02:00
//Enregistrement de la frame openCV
2017-05-09 18:01:10 +02:00
cvSaveImage ( " Stock SFML/temp.jpg " , frame ) ;
2017-05-09 16:44:50 +02:00
//Chargement de la frame en texture SFML
2017-05-09 18:01:10 +02:00
if ( ! txFlux . loadFromFile ( " Stock SFML/temp.jpg " ) ) {
2017-05-09 16:44:50 +02:00
printf ( " Erreur chargement image SFML \n " ) ;
break ;
}
2017-05-02 18:17:11 +02:00
spFlux . setTexture ( txFlux ) ;
2017-05-09 18:01:10 +02:00
window . draw ( spFlux ) ;
2017-05-02 18:17:11 +02:00
2017-05-23 14:30:22 +02:00
2017-05-09 21:53:20 +02:00
sf : : Vector2i PosMouse = sf : : Mouse : : getPosition ( window ) ;
2017-05-23 14:30:22 +02:00
//Detection du bouton tracking
2017-05-09 21:53:20 +02:00
if ( sf : : Mouse : : isButtonPressed ( sf : : Mouse : : Left ) & & ( PosMouse . x > 640 ) & & ( PosMouse . x < 760 ) & & ( PosMouse . y > 0 ) & & ( PosMouse . y < 120 ) ) {
//printf("\n\n\n OK \n\n\n");
if ( tracking ) { tracking = 0 ; }
else tracking = 1 ;
2017-05-16 17:36:09 +02:00
cvWaitKey ( 100 ) ;
2017-05-09 18:01:10 +02:00
}
2017-05-09 21:53:20 +02:00
//printf("Pos Mouse : %d %d \n", PosMouse.x, PosMouse.y);
2017-05-23 14:30:22 +02:00
//Dessin du bouton de tracking
2017-05-16 17:36:09 +02:00
sf : : Texture txBut ;
sf : : Sprite button_tracking ;
if ( ! txBut . loadFromFile ( " Stock SFML/button.png " ) ) {
printf ( " Erreur chargement image SFML \n " ) ;
break ;
}
2017-05-02 18:17:11 +02:00
2017-05-16 17:36:09 +02:00
button_tracking . setTexture ( txBut ) ;
button_tracking . setScale ( 0.5 , 0.5 ) ;
button_tracking . setPosition ( sf : : Vector2f ( width + 20 , 20 ) ) ;
2017-05-09 18:01:10 +02:00
2017-05-16 17:36:09 +02:00
if ( tracking ) { button_tracking . setColor ( sf : : Color : : Green ) ; }
else { button_tracking . setColor ( sf : : Color : : Red ) ; }
2017-05-09 18:01:10 +02:00
2017-05-16 17:36:09 +02:00
window . draw ( button_tracking ) ;
2017-05-09 18:01:10 +02:00
2017-05-23 14:30:22 +02:00
//Ajout du texte
2017-05-09 21:53:20 +02:00
sf : : Font font ;
if ( ! font . loadFromFile ( " Stock SFML/arial.ttf " ) ) {
printf ( " Erreur chargement police SFML \n " ) ;
break ;
2017-05-09 18:01:10 +02:00
}
2017-05-09 21:53:20 +02:00
sf : : Text text ;
// choix de la police à utiliser
text . setFont ( font ) ; // font est un sf::Font
// choix de la chaîne de caractères à afficher
2017-05-16 17:36:09 +02:00
text . setString ( " Tracking Moteur " ) ;
2017-05-09 21:53:20 +02:00
// choix de la taille des caractères
text . setCharacterSize ( 24 ) ; // exprimée en pixels, pas en points !
//text.setFillColor(sf::Color::Black);
text . setColor ( sf : : Color : : Black ) ;
2017-05-16 17:36:09 +02:00
text . setPosition ( sf : : Vector2f ( width + 100 , 35 ) ) ;
2017-05-09 21:53:20 +02:00
window . draw ( text ) ;
2017-05-01 20:45:20 +02:00
2017-05-02 18:17:11 +02:00
/* Update the window */
2017-05-09 16:44:50 +02:00
window . display ( ) ;
2017-05-01 20:45:20 +02:00
2017-05-02 18:17:11 +02:00
# endif
2017-05-23 14:30:22 +02:00
//Envoie données moteurs
2017-05-09 21:53:20 +02:00
if ( tracking ) {
2017-05-09 16:29:35 +02:00
//Mouvements moteurs
2017-05-16 17:36:09 +02:00
//printf("-PREMAJ_ANGLE...: %d %d\n",width,height);
2017-05-09 16:56:07 +02:00
2017-05-16 17:36:09 +02:00
maj_angle ( ajust_pos ( posX - width / 2 , width ) , ajust_pos ( posY - height / 2 , height ) , height * JEU , angle ) ;
2017-05-09 16:29:35 +02:00
controle_moteur ( angle ) ;
2017-05-09 18:12:04 +02:00
2017-05-16 17:36:09 +02:00
cvWaitKey ( 50 ) ;
2017-05-09 21:53:20 +02:00
}
2017-05-16 17:36:09 +02:00
2017-05-03 13:11:28 +02:00
2017-05-02 18:17:11 +02:00
# ifdef CONFIG
2017-05-09 16:29:35 +02:00
affichage_config ( frame , hsv_frame , threshold ) ; //Affichage du flux vidéo et de ses traitements
2017-05-03 13:11:28 +02:00
2017-05-09 16:29:35 +02:00
if ( ( cvWaitKey ( 10 ) ) > = 0 ) break ; //Arret capture
2017-05-02 18:17:11 +02:00
# endif
2017-05-09 16:29:35 +02:00
}
2017-05-01 20:45:20 +02:00
2017-05-09 16:29:35 +02:00
// Release the capture device housekeeping
cvReleaseCapture ( & capture ) ;
2017-05-01 20:45:20 +02:00
2017-05-09 16:29:35 +02:00
cvReleaseImage ( & threshold ) ;
cvReleaseImage ( & hsv_frame ) ;
cvReleaseImage ( & frame ) ;
2017-05-01 20:45:20 +02:00
2017-05-09 16:29:35 +02:00
return EXIT_SUCCESS ;
}
2017-05-01 20:45:20 +02:00
2017-05-09 18:09:07 +02:00
void maj_angle ( int vecX , int vecY , int rayon , double * angle ) {
2017-05-09 16:29:35 +02:00
//On ajustera coeff fonction du rayon. Si la cible est à une distance 5*r, il sera 5x plus rapide que s'il était à 1*r
2017-05-09 16:56:07 +02:00
2017-05-09 18:09:07 +02:00
double coeffx , coeffy ;
int l0 , l1 ;
2017-05-09 16:56:07 +02:00
2017-05-16 17:36:09 +02:00
//printf("-MAJ_ANGLE...Valeur maj_angle arguments : %d %d %d\n\tAnciens angles : %d %d\n\t",vecX,vecY,rayon,(int)angle[0],(int)angle[1]);
2017-05-01 20:45:20 +02:00
2017-05-09 16:29:35 +02:00
2017-05-09 16:56:07 +02:00
//Ajout d'un angle moteur pondéré par la distance
2017-05-16 17:36:09 +02:00
coeffx = - 0.2 * vecX / rayon ;
coeffy = 0.2 * vecY / rayon ;
2017-05-09 16:56:07 +02:00
angle [ 0 ] + = coeffx ;
angle [ 1 ] + = coeffy ;
//Majoration - minoration des angles moteurs
l0 = limite_moteur ( angle [ 0 ] ) ;
l1 = limite_moteur ( angle [ 1 ] ) ;
if ( l0 ! = 0 ) angle [ 0 ] = l0 ;
if ( l1 ! = 0 ) angle [ 1 ] = l1 ;
2017-05-16 17:36:09 +02:00
//printf("Nouveaux angles : %lf %lf %d %d\n",angle[0],angle[1],(int)angle[0],(int)angle[0]);
2017-05-09 16:56:07 +02:00
}
2017-05-09 16:29:35 +02:00
2017-05-09 16:56:07 +02:00
int ajust_pos ( int pos , int ref ) {
if ( pos > ref ) return 0 ;
else return pos ;
2017-05-09 16:29:35 +02:00
}
int limite_moteur ( int val_pwm ) {
int MAX_PWM = 130 , MIN_PWM = 30 ;
if ( val_pwm > MAX_PWM ) {
return MAX_PWM ;
2017-05-01 20:45:20 +02:00
}
2017-05-09 16:29:35 +02:00
else if ( val_pwm < MIN_PWM ) {
return MIN_PWM ;
}
else {
return 0 ;
}
}
2017-05-01 20:45:20 +02:00
2017-05-09 18:09:07 +02:00
void controle_moteur ( double * angle ) {
2017-05-09 16:29:35 +02:00
//Ouverture port serie
FILE * fichier = NULL ;
2017-05-01 20:45:20 +02:00
fichier = fopen ( " /dev/ttyACM0 " , " w " ) ;
if ( fichier = = NULL ) {
printf ( " Erreur ouverture fichier \n " ) ;
2017-05-09 16:29:35 +02:00
perror ( " fopen failed for /dev/ttyACM0 " ) ;
exit ( EXIT_FAILURE ) ;
2017-05-01 20:45:20 +02:00
}
2017-05-09 16:29:35 +02:00
//Ecriture angles
2017-05-09 18:09:07 +02:00
fprintf ( fichier , " %d \n " , ( int ) angle [ 0 ] ) ;
fprintf ( fichier , " %d \n " , ( int ) angle [ 1 ] ) ;
2017-05-09 16:29:35 +02:00
//Fermeture
2017-05-01 20:45:20 +02:00
fclose ( fichier ) ;
return ;
}
2017-05-03 13:11:28 +02:00
void traitement ( IplImage * frame , IplImage * HSV , IplImage * Binaire , int LowH , int HighH , int LowS , int HighS , int LowV , int HighV ) { //Effectue une binarisation de frame en fonction des bornes HSV
// Covert color space to HSV as it is much easier to filter colors in the HSV color-space.
cvCvtColor ( frame , HSV , CV_BGR2HSV ) ;
//Blur
cvSmooth ( HSV , HSV , CV_GAUSSIAN , 15 , 0 , 0 , 0 ) ; //suppression des parasites par flou gaussien
//Binarisation
2017-05-16 17:36:09 +02:00
CvScalar valinf = { ( double ) LowH , ( double ) LowS , ( double ) LowV } ;
CvScalar valsup = { ( double ) HighH , ( double ) HighS , ( double ) HighV } ;
2017-05-03 13:11:28 +02:00
2017-05-16 17:36:09 +02:00
cvInRangeS ( HSV , valinf , valsup , Binaire ) ;
2017-05-09 21:53:20 +02:00
2017-05-09 16:44:50 +02:00
//En cas d'erreur sur les trois ligne précédentes
2017-05-16 17:36:09 +02:00
//cvInRangeS(HSV, CvScalar(LowH,LowS,LowV),CvScalar(HighH,HighS,HighV), Binaire);
2017-05-03 13:11:28 +02:00
//cvSmooth( Binaire, Binaire, CV_GAUSSIAN, 9, 9 ); //Legère suppression des parasites
}
void Position_moy ( IplImage * Binaire , int * posX , int * posY ) { //Effectue le baricentre des pixels d'une image binaire pour obtenir la postion de l'objet
CvMoments * moments = ( CvMoments * ) malloc ( sizeof ( CvMoments ) ) ;
cvMoments ( Binaire , moments , 1 ) ;
// The actual moment values
double moment10 = cvGetSpatialMoment ( moments , 1 , 0 ) ;
double moment01 = cvGetSpatialMoment ( moments , 0 , 1 ) ;
double area = cvGetCentralMoment ( moments , 0 , 0 ) ;
* posX = moment10 / area ;
* posY = moment01 / area ;
free ( moments ) ;
}
void config ( int * LowH , int * HighH , int * LowS , int * HighS , int * LowV , int * HighV ) { //Affiche le panneau de configuration de tracking avec les arguments comme valeur de base
cvNamedWindow ( " Control " , CV_WINDOW_AUTOSIZE ) ; //create a window called "Control"
//Create trackbars in "Control" window
cvCreateTrackbar ( " LowH " , " Control " , LowH , 179 , NULL ) ; //Hue (0 - 179)
cvCreateTrackbar ( " HighH " , " Control " , HighH , 179 , NULL ) ;
cvCreateTrackbar ( " LowS " , " Control " , LowS , 255 , NULL ) ; //Saturation (0 - 255)
cvCreateTrackbar ( " HighS " , " Control " , HighS , 255 , NULL ) ;
cvCreateTrackbar ( " LowV " , " Control " , LowV , 255 , NULL ) ; //Value (0 - 255)
cvCreateTrackbar ( " HighV " , " Control " , HighV , 255 , NULL ) ;
}
void affichage_config ( IplImage * frame , IplImage * HSV , IplImage * Binaire ) { //Affiche le flux vidéos et ses différent traitements
// Create a window in which the captured images will be presented
cvNamedWindow ( " HSV " , CV_WINDOW_AUTOSIZE ) ;
cvNamedWindow ( " Binaire " , CV_WINDOW_AUTOSIZE ) ;
cvNamedWindow ( " Camera " , CV_WINDOW_AUTOSIZE ) ;
cvShowImage ( " HSV " , HSV ) ; // Original stream in the HSV color space
cvShowImage ( " Binaire " , Binaire ) ; // The stream after color filtering
cvShowImage ( " Camera " , frame ) ; // Flux caméra avec tracking objet
}
void Affichage_Tracking ( IplImage * frame , int posX , int posY , int width , int height ) { //Dessine les informations de tracking sur frame
//Affichage zone suivie objet
2017-05-16 17:36:09 +02:00
cvCircle ( frame , cvPoint ( width / 2 , height / 2 ) , height * JEU , CV_RGB ( 0 , 255 , 0 ) , 4 , 8 , 0 ) ;
2017-05-03 13:11:28 +02:00
if ( posX < 5 & & posY < 5 ) { //Si aucun objet spotted, pointeur rouge au centre
posX = width / 2 ;
posY = height / 2 ;
cvLine ( frame , cvPoint ( posX - 20 , posY ) , cvPoint ( posX + 20 , posY ) , CV_RGB ( 255 , 0 , 0 ) , 4 , 8 , 0 ) ;
cvLine ( frame , cvPoint ( posX , posY - 20 ) , cvPoint ( posX , posY + 20 ) , CV_RGB ( 255 , 0 , 0 ) , 4 , 8 , 0 ) ;
}
else { //Objet spotted
//Affichage position de l'objet
cvLine ( frame , cvPoint ( posX - 20 , posY ) , cvPoint ( posX + 20 , posY ) , CV_RGB ( 0 , 0 , 255 ) , 4 , 8 , 0 ) ;
cvLine ( frame , cvPoint ( posX , posY - 20 ) , cvPoint ( posX , posY + 20 ) , CV_RGB ( 0 , 0 , 255 ) , 4 , 8 , 0 ) ;
}
}