un code complete.
Transcription
un code complete.
Algorithmique, C++ Recollement d'images Objectif du TP : programmation d'un algorithme de recollement d'images Langage C++ Algorithmique et structures de données Application de notions vues en CTD Algos de programmation dynamique et Dijkstra Structures de données, calculs de coûts Programmation efficace et optimisations Introduction au langage Gestion de la mémoire, héritage, généricité, Standard Template Library (STL), ... Options de compilation, outils de profilage, ... Débogage de programmes Déroulement 4 séances de cours + 7 séances en salle machine + 1 séance de TD (planning : cf. wikiosk) Travailler sur votre compte sur ensibm 3 délivrables, sur 2/2/1 point(s), à rendre à la fin de 3 séances machines (Teide) Note de TP = ¼ de la note d'algo Séances notées Nouveauté : une note pour 2 séances consécutives (5 et 6, 8 et 9, 11 et 12) Enoncé fourni au début de la première séance Travail à effectuer pour le début de la seconde séance Début de la seconde séance : questionnaire + énoncé complémentaire Ce qui vous est fourni Poly (cf. wikiosk) : Enoncé du sujet global du TP Introduction à C++ (non exhaustif !) Des fichiers sources Au début des séances de TP Eventuellement incomplets Des images pour les tests Vous pouvez aussi en utiliser d'autres Ce qui doit être rendu A la fin des séances n° 6, 9 et 12 Un code complété Un questionnaire rempli Via Teide Travail en monômes (Hopefully) Retour/correction lors de la séance suivante Questionnaire Début de séance 2/2, questions de compréhension sur la 1ère partie Code de la séance 1/2 pas forcément corrigé Certains, pris au hasard, seront corrigés Note ≠note du questionnaire => sanction Vous pouvez demander une correction individualisée Rq: toutes les séances en salles machines sont obligatoires (-1 pt sur la note finale par absence) Sujet du TP : recollement d'images Une image numérique est constituée d'un tableau d'éléments de base appelés pixels Pixel = PICTure ELement A chaque pixel est associée une couleur : triplet de scalaires (R,V,B) R : Rouge, V : Vert, B : Bleu Recollement d'images Soient deux images I1 et I2 deux vues voisines de la même scène, placées en partie l’une sur l’autre pour qu’elles se raccordent le mieux possible. J : zone de chevauchement (Rectangle de taille n x m pixels) I1 J I2 Deux images se chevauchant Recollement d'images Chemin dans J : suite de pixels voisins ∈ J I1 I2 Erreur entre les images en un pixel p ∈ J de couleur (R1,V1,B1) dans I1 et de couleur (R2,V2,B2) dans I2 2 2 2 ε(p) = (R1 − R2 ) +(V1 − V2 ) +(B1 − B2 ) Recollement d'images Coût d'un chemin tracé dans J = somme des erreurs des pixels qui forment le chemin But : raccordement entre les images le moins visible possible Calculer le chemin de coût minimal Image I1 affichée à gauche de ce chemin, Image I2 à sa droite. Recollement d'images Recollement d'images Objectifs des séances de TP : Préparer les classes et méthodes utiles Calculer un chemin optimal : Plusieurs algorithmes Tester et comparer ces algorithmes Tests : n'hésitez pas à utiliser vos propres photos ! Plan des séances de cours Aujourd'hui (séance n° 1) Présentation du sujet du TP De Java et C à C++ Séance n° 3 Séance n° 7 Héritage, généricité STL et structures de données Séance n° 10 Optimisation, débogage, exceptions, … Introduction à C++ Première partie De Java et C à C++ Introduction Langage objet : classes, héritage, généricité… C++ peut être considéré comme extension de C (en première approximation) C est un sous-ensemble de C++ (à peu de choses près) Pas de garbage collector (≠ Java) Bibliothèque Standard : STL Structures de données Algos standards “Héritage” du C Types de base : int, double, float, char… Arithmétique de base : +, - , *, /, %, … Tests et boucles : if (condition) { insts; } else { insts; } for (int i=0; i<n; i++) { insts;} while (condition) {insts;} do {insts;} while(condition); Pointeurs et tableaux : char v[10]; int *i; Extensions des fonctions Surcharge de fonctions : int puissance(int x, int n){ //calcule xn = x.x…x } double puissance(int x, double n){ //calcule xn = en log x } Arguments par défaut d’une fonction int ajouter(int a, int b=1) { return a+b; } ajouter(2); // renvoie 3 Gestion de la mémoire 2 nouveaux opérateurs de gestion de la mémoire : new type : allocation d'un objet unique new type[n] : allocation d'un tableau de taille n delete adresse : libération d'un objet unique delete [] adresse : libération d'un tableau Plus de malloc, allocation dynamique Attention aux fuites de mémoire ! Gestion de la mémoire Exemple : int* pi = new int; // Au lieu de : // int *pi = (int *) malloc(sizeof(int)); float* RGB = new float[3]; … delete pi; // Au lieu de : free(pi); delete [] RGB; Références Notion de référence : & & (ampersand) = alias sur une variable ou un objet. Exemple : int ix; int &ir = ix; // Est une ref sur ix ir = j; // Ne transforme pas ir en ref sur j // mais copie j dans ix ix = 1; // ir = 1 aussi ir = 2; // ix = 2 aussi Passage de Paramètres : void Recopie(int &i); Entrées/sorties de base Soit printf, scanf… , soit utilisation des flux. #include <iostream> Entrée clavier : int i; std::cin >> i; // Lit un entier Sortie à l'écran : int i = 2; std::cout << "i : " << i << std::endl; Flux d'erreur : std::cerr << "erreur !" << std::endl; Entrées/sorties fichier Exemple : ifstream f("infile"); // Ouverture en lecture ofstream g("outfile");// Ouverture en écriture fstream h("filename",ios::in|ios::out); //Ouverture en lecture et écriture char buf[81]; f.getline(buf, 80); // Lit une ligne while (f) { g << buf << std::endl; // Envoie dans g f.getline(buf,80); // Lit la ligne suivante } Espace de nommage Équivalent du paquetage Java et Ada Défini à l’aide du mot-clé namespace Intérêt : éviter les conflits de noms entre plusieurs modules. namespace pile_de_char { void empiler(char); char depiler(); } namespace pile_de_int { void empiler(int); int depiler(); } Espace de nommage : utilisation Exemple : void main(){ pile_de_char::empiler( ‘x’ ); if (pile_de_char::depiler() != ‘x’) std::cerr << "impossible" << std::endl; } Mot-clé using : introduit l'identificateur dans la région déclarative courante : using pile_de_char::empiler(char); => empiler('x'); Les classes Définition d'un nouveau type C++ Une classe est composée : d'attributs (données internes) de fonctions membres appelées méthodes Une variable de ce type (une instance) est appelée un objet Encapsulation : déclaration méthodes et attributs à un endroit unique Un exemple de classe class Point { int _x, _y; int abscisse () const { return _x; } int ordonnee () const { return _y; } void set_coord (int x, int y) { _x = x; _y = y; } }; Exemple d'utilisation void main() { Point p; p.set_coord(1,2); std::cout << "abscisse : " << p.abscisse() << " ordonnee : " << p.ordonnee() << std::endl; } Accès aux attributs et méthodes L'utilisateur peut restreindre l'accès aux attributs et fonctions membres de ses classes : public, private, protected private : autorisé uniquement aux fonctions membres de la classe public : autorisé pour toute fonction protected : autorisé uniquement aux fonctions membres de la classe et aux classes dérivées Conseil d'utilisation : tous les attributs privés Un exemple d'utilisation class Point { private: // Pas obligatoire, par défaut ! int _x, _y; public: // Les méthodes suivantes sont publiques int abscisse () const { return _x; } int ordonnee () const { return _y; } void set_coord (int x, int y) { _x = x; _y = y; } }; Constructeurs Rôle (principalement) : allouer la mémoire initialiser les attributs Par défaut sont implémentés : constructeur vide constructeur de recopie Constructeurs : exemple class Point { int _x, _y; public : Point() : _x(0), _y(0) {} // Constructeur par défaut ; celui qui est appelé lors d'une déclaration du type : // Point p; Point(int x, int y) : _x(x), _y(y) {} // Constructeur appelé lors d'une déclaration du type : // Point p(1,2); Point(const Point& P) : _x(P._x), _y(P._y){} // Constructeur de recopie : // Point p1; // Point p2(p1); // p2 est une copie de p1 }; Eléments de syntaxe Liste d'initialisation d'un constructeur : Point() : _x(0),_y(0) {…} Fonctions membres constantes : ne modifient pas les attributs de la classe class Point { int _x, _y; public: int abscisse() const { return _x; } … }; Destructeurs Rôle : libérer la mémoire ! Appelés automatiquement à la fin de la portée de l'objet (fermeture d'accolade } ) Par défaut un destructeur vide est implémenté Destructeur : exemple class Tableau { int *_t; public: Tableau(int s = 10) { _t = new int[s]; } ~Tableau() { delete [] _t; } }; { Tableau T; … } // Destructeur ~Tableau() appelé automatiquement // en fin de portée Séparation déclaration/implantation Fichier Point.h : Class Point { int _x, _y; Public: int abscisse() const; … }; Fichier Point.cpp : Point::Point() : _x(0), _y(0) {} int Point::abscisse() const {return _x;} Références croisées Problème : toto.h titi.h #include "titi.h" class toto { void f1(titi t); }; toto.cpp #include "toto.h" class titi { void f1(toto t); }; titi.cpp #include "toto.h" void toto::f1(titi t){…} #include "titi.h" void titi::f1(toto t){…} NE FONCTIONNE PAS !! Références croisées Solution : prédéclarations toto.h class titi; class toto { void f1(titi t); }; toto.cpp #include "toto.h" #include "titi.h" void toto::f1(titi t){…} titi.h class toto; class titi { void f1(toto t); }; titi.cpp #include "titi.h" #include "toto.h" void titi::f1(toto t){…}