245 lines
7.3 KiB
C++
245 lines
7.3 KiB
C++
/*
|
|
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<n°-de-la-planche>-<vos-noms>.cpp
|
|
- écrivez ci-dessous vos NOMS Prénoms et la date de la version :
|
|
|
|
<NOM1 Prénom1> [et <NOM2 Prénom2>] - version du <date>
|
|
*/
|
|
|
|
|
|
#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<cv::Vec3b>(y,x)[0] = coulB;
|
|
img_coul.at<cv::Vec3b>(y,x)[1] = coulG;
|
|
img_coul.at<cv::Vec3b>(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<cv::Vec3b>(y,x)[0] = 255 - img_coul.at<cv::Vec3b>(y,x)[0];
|
|
img_coul.at<cv::Vec3b>(y,x)[1] = 255 - img_coul.at<cv::Vec3b>(y,x)[1];
|
|
img_coul.at<cv::Vec3b>(y,x)[2] = 255 - img_coul.at<cv::Vec3b>(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<int>(y,x) = img_niv.at<int>(y,x) - img_niv.at<int>(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<int>(y,x);
|
|
// Attention img_coul est en B, G, R
|
|
if (g >= 0) {
|
|
img_coul.at<cv::Vec3b>(y,x)[0] = 0;
|
|
img_coul.at<cv::Vec3b>(y,x)[1] = g % 256; // Vert
|
|
img_coul.at<cv::Vec3b>(y,x)[2] = 0;
|
|
} else {
|
|
img_coul.at<cv::Vec3b>(y,x)[0] = 0;
|
|
img_coul.at<cv::Vec3b>(y,x)[1] = 0;
|
|
img_coul.at<cv::Vec3b>(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<int>(nature_dessin)+1;
|
|
nature_dessin = static_cast<NatureDessin>(suiv);
|
|
if (nature_dessin == D_LAST) nature_dessin = D_BLANC;
|
|
std::cout << "Nature dessin : "
|
|
<< nom_dessins[static_cast<int>(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 ();
|
|
}
|
|
|