/* demo2.cpp - exemple d'utilisation de Astico2D CC BY-SA Edouard.Thiel@univ-amu.fr - 22/08/2021 Usage : $ make demo2 $ ./demo2 [-mag width height] [-thr seuil] image_in [image_out] */ /* Pour le rendu de TP : - renommez ce fichier tp-.cpp - écrivez ci-dessous vos NOMS Prénoms et la date de la version : [et ] - version du */ #include "astico2d.hpp" //----------------------- T R A N S F O R M A T I O N S ----------------------- // Placez ici vos fonctions de transformations à la place de ces exemples enum NatureDessin { D_BLANC, D_NOIR, D_BLEU, D_INV, D_LAST }; char const *nom_dessins[4] = {"blanc", "noir", "bleu", "inverse"}; void dessiner_damier_couleur (cv::Mat &img_coul, int taille, int coulR, int coulG, int coulB) { CHECK_MAT_TYPE(img_coul, CV_8UC3); for (int y = 0; y < img_coul.rows; y++) for (int x = 0; x < img_coul.cols; x++) { int numero_case_x = x / taille; int numero_case_y = y / taille; if ((numero_case_x + numero_case_y) % 2) { // Attention img_coul est en B, G, R img_coul.at(y,x)[0] = coulB; img_coul.at(y,x)[1] = coulG; img_coul.at(y,x)[2] = coulR; } } } void dessiner_damier_inverse (cv::Mat &img_coul, int taille) { CHECK_MAT_TYPE(img_coul, CV_8UC3); for (int y = 0; y < img_coul.rows; y++) for (int x = 0; x < img_coul.cols; x++) { int numero_case_x = x / taille; int numero_case_y = y / taille; if ((numero_case_x + numero_case_y) % 2) { img_coul.at(y,x)[0] = 255 - img_coul.at(y,x)[0]; img_coul.at(y,x)[1] = 255 - img_coul.at(y,x)[1]; img_coul.at(y,x)[2] = 255 - img_coul.at(y,x)[2]; } } } void dessiner_damier (cv::Mat &img_coul, int taille, NatureDessin nat) { switch (nat) { case D_BLANC : dessiner_damier_couleur (img_coul, taille, 255, 255, 255); break; case D_NOIR : dessiner_damier_couleur (img_coul, taille, 0, 0, 0); break; case D_BLEU : dessiner_damier_couleur (img_coul, taille, 0, 0, 255); break; case D_INV : dessiner_damier_inverse (img_coul, taille); break; default : std::cout << "Erreur, nature de dessin non prevu" << std::endl; } } void calculer_differences_en_x (cv::Mat &img_niv) { CHECK_MAT_TYPE(img_niv, CV_32SC1); // Remarque : l'image img_niv étant seuillée (valeurs 0 ou 255), le // résultat sera dans { -255, 0, 255 }. for (int y = img_niv.rows-1; y > 0; y--) for (int x = img_niv.cols-1; x > 0; x--) { img_niv.at(y,x) = img_niv.at(y,x) - img_niv.at(y,x-1); } } void representer_en_rouge_ou_vert (cv::Mat &img_niv, cv::Mat &img_coul) { CHECK_MAT_TYPE(img_niv, CV_32SC1); CHECK_MAT_TYPE(img_coul, CV_8UC3); // Palette rouge dans les valeurs négatives, vert dans les valeurs positives for (int y = 0; y < img_niv.rows; y++) for (int x = 0; x < img_niv.cols; x++) { int g = img_niv.at(y,x); // Attention img_coul est en B, G, R if (g >= 0) { img_coul.at(y,x)[0] = 0; img_coul.at(y,x)[1] = g % 256; // Vert img_coul.at(y,x)[2] = 0; } else { img_coul.at(y,x)[0] = 0; img_coul.at(y,x)[1] = 0; img_coul.at(y,x)[2] = (-g) % 256 ; // Rouge } } } //----------------------------- I N T E R F A C E ----------------------------- class MonApp : public Astico2D { public: // Déclarez ici d'autres membres éventuels int taille = 20, taille_max = 100; NatureDessin nature_dessin = D_BLANC; MonApp (int argc, char **argv) : Astico2D (argc, argv) // initialisez ici vos classes membre éventuelles { if (!init_ok) return; // erreur dans l'initialisation // On crée ici un slider "Taille" qui manipulera le membre taille de 0 // à taille_max. creer_slider ("Taille", &taille, taille_max); // On affiche les arguments supplémentaires de la ligne de commande std::cout << "Arguments restant : argc = " << argc; if (argc > 0) { std::cout << " argv ="; for (int i = 0; i < argc; i++) std::cout << " " << argv[i]; } std::cout << std::endl; } void afficher_touches_clavier () override { // Ceci affiche l'aide de base Astico2D::afficher_touches_clavier (); // Indiquez ici les touches du clavier et vos transformations std::cout << " 1 dessine un damier sur l'image seuillee\n" " tT deplace le slider Taille\n" " n change la nature du dessin\n" << std::endl; } bool traiter_touche_clavier (char key) override { switch (key) { // Gérez ici les touches de flags. case 't' : diminuer_slider ("Taille", 0); break; case 'T' : augmenter_slider ("Taille", taille_max); break; case 'n' : { int suiv = static_cast(nature_dessin)+1; nature_dessin = static_cast(suiv); if (nature_dessin == D_LAST) nature_dessin = D_BLANC; std::cout << "Nature dessin : " << nom_dessins[static_cast(nature_dessin)] << std::endl; break; } // Rajoutez ici les touches pour effectuer_transformations. case '1' : // On mémorise la touche pressée touche_transfo = key; // On précise le mode : M_NIVEAUX ou M_COULEURS mode_transfo = M_COULEURS; break; case '2' : touche_transfo = key; mode_transfo = M_NIVEAUX; break; default : return false; // touche non traitée } return true; // touche traitée } void effectuer_transformations () override { // Appelez ici vos transformations selon touche_transfo et mode_transfo : // - si mode_transfo est M_NIVEAUX, l'image d'entrée est l'image seuillée // img_niv, de type CV_32SC1 ; à la fin, pour l'affichage, il faut la // convertir en couleur dans img_coul, de type CV_8UC3, par exemple avec // representer_en_couleurs_vga. // - si mode_transfo est M_COULEURS, travaillez directement sur img_coul, // de type CV_8UC3, elle sera affichée telle quelle. switch (touche_transfo) { case '1' : // M_COULEURS dessiner_damier (img_coul, taille, nature_dessin); break; case '2' : // M_NIVEAUX calculer_differences_en_x (img_niv); representer_en_rouge_ou_vert (img_niv, img_coul); break; } } }; //---------------------------------- M A I N ---------------------------------- int main (int argc, char **argv) { MonApp app (argc, argv); return app.run (); }