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

 C Discussion :

Programmer un effet de relief sur une image


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé

    Homme Profil pro
    autre
    Inscrit en
    Juillet 2015
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Juillet 2015
    Messages : 176
    Par défaut Programmer un effet de relief sur une image
    Bonjour.
    J'ai modifié une fonction déjà existante sur le net pour l'adapter à mon programme.
    Mon but était de donner du relief à une image.
    Voici la fonction en question :

    Code c : 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
    image image_filter_rect_aux2 (image* I, int x1, int y1, int x2, int y2, int* K, int kCols, int kRows, int divisor)
    {
     
     int kCenterX = kCols / 2;
     int kCenterY = kRows / 2;
     int i, j, m, mm, n, nn, ii, jj;
     
     image J = image_create ((*I)->w, (*I)->h, 0xffffffff);
     
     
     for(j = y1 + 1 ; j < y2 - 1  ; j++)            
     {
        for(i = x1  + 1; i < x2 - 1 ; i++)         
        {
     
         byte r=0;
         byte g=0;
         byte b=0;
     
            for(m=0; m < kRows; m++)    
            {
                mm = kRows - 1 - m;      
     
                for(n=0; n < kCols; n++) 
                {
     
     
                    ii = i + (m - kCenterX);/*changer le i + et le j + en i - et en j - pour changer impression de relief*/
                    jj = j - (n - kCenterY);
                    if( ii >= 0 && ii < (*I)->w && jj >= 0 && jj < (*I)->h )
                     {
                       byte rr, gg, bb;
     
                       nn = kCols + 1 + n;
     
                       colour_get_rgb ((*I)->pixel [jj * (*I)->w + ii]  , &rr, &gg, &bb);  
     
                       r += (rr * (K[mm * kRows + nn])) / divisor ;
                       g += (gg * (K[mm * kRows + nn])) / divisor;
                       b += (bb * (K[mm * kRows + nn])) / divisor;
     
                       image_putpixel (J, i, j, make_colour(r, g, b, 0xff));
     
                     }   
                }
            }
        }
     }
     
    for (j = 0; j < J->h; j++)
     {
      for (i = 0; i < J->w; i++)
       {
        byte a, b, c;
        colour_get_rgb (J->pixel[j * J->w + i], &a, &b, &c);
        J->pixel[j * J->w + i] = make_colour (255-a, 255-b, 255-c, 0xff);
       }
     }
     
    /*
    for (j = 0; j < J->h; j++)
     {
      for (i = 0; i < J->w; i++)
       {
        byte a, b, c;
        colour_get_rgb (J->pixel[j * J->w + i], &a, &b, &c);
        if (J->pixel[j * J->w + i] == 0xffffffff)
         J->pixel[j * J->w + i] = make_colour (180, 180, 180, 0xff);
       }
     }
    */
     
     return J;
    }


    Quand je compare mon image (la première) à celle obtenue avec The Gimp (la seconde image), Je préfère le résultat obtenu avec The Gimp (ah bon? ça alors, c'est étonnant...)

    Voici ma question : Avec The Gimp, pour obtenir cet effet, on va dans Filtres => Distorsions => relief.

    Une fois là, on le choix de modifier : Azimut, Elevation, Profondeur. (il y a ausi le choix entre carte de relief et relief).

    Savez vous comment il serait possible de modifier la fonction que j'utilise pour paramétrer l'elevation, la profondeur et l'Azimut svp? ( + carte de relief et relief : quelle est la signification de tous ces termes?).

    De plus, quelle est la méthode pour "lisser" l'image et ne pas se retrouver, comme moi, avec des pixels tout pourris?

    Merci d'avance.

    image 1 (moi), image 2 (The Gimp )
    Images attachées Images attachées   

  2. #2
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 766
    Par défaut
    Commence par t'amuser avec les matrices de convolution :

    Une petite mise en bouche:

  3. #3
    Membre confirmé

    Homme Profil pro
    autre
    Inscrit en
    Juillet 2015
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Juillet 2015
    Messages : 176
    Par défaut
    Bonjour foetus.

    il y a un truc qui cloche dans ma fonctin, c'est sûr. Par exemple, quand j'applique la fonction (encore modifiée) suivante avec ce filtre et ces paramètres, j'obtiens l'image suivante. Ce qui n'est pas du tout le résultat attendu.

    Comment se débarrasser des pixels qui bruitent (c'est à dire ceux dont la couleur tranche trop avec la couleur de contexte de l'image)?

    Ne vaudrait il mieux pas passer par des coefficients à virgule, quitte à recalculer chaque pixel pour que la valeur de ceux ci s'approchent de la valeur au dessus / au dessous (par exemple 0.6 donne 1 et 0.4 donne 0)

    le résultat est le même avec une image 512 x 512 qu'avec une image 2200 x 1600




    Code c : 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
    /*filtre*/
    int* laplacien[5*5] = {
      -1, -1, -1, -1, -1,
      -1, -1, -1, -1, -1,
     
      -1, -1, 24, -1, -1,
      -1, -1, -1, -1, -1,
      -1, -1, -1, -1, -1,  
    }; 
     
    /*Appel de la fonction*/
    image J = image_convolution (&I, 0, 0, 512, 512, &laplacien, 5, 5, 5, 7);
     
     
    /*Fonction elle même*/
     
    image image_convolution (image* I, int x1, int y1, int x2, int y2, int* K, int kCols, int kRows, int divisor, int luminosite)
    {
     
     int kCenterX = kCols / 2;
     int kCenterY = kRows / 2;
     int i, j, m, mm, n, nn, ii, jj;
     
    image J = image_create ((*I)->w, (*I)->h, 0xffffffff);
     
     
     
     
     for(j = y1 + kRows; j < y2 - kRows ; j++)            
     {
     
        for(i = x1 + kCols ; i < x2 - kCols; i++)         
        {
         byte r=0;
         byte g=0;
         byte b=0;
     
            for(m=0; m < kRows; m++)    
            {
                mm = kRows + 1 + m;      
     
                for(n=0; n < kCols; n++) 
                {
                    nn = kCols - 1 - n;
     
     
                    ii = i + (n + kCenterX);
                    jj = j + (n + kCenterY);
     
     
                    if( ii >= 0 && ii < (*I)->w && jj >= 0 && jj < (*I)->h )
                     {
                       byte rr, gg, bb;
     
                       colour_get_rgb ((*I)->pixel [jj * (*I)->w + ii], &rr, &gg, &bb);  
     
     
                       r += ((rr * (K[nn * kRows + mm])/divisor)+ luminosite) ;
     
                       g += ((gg * (K[nn * kRows + mm])/divisor) + luminosite) ;
     
                       b += ((bb * (K[nn * kRows + mm])/divisor) + luminosite) ;
     
     
                       image_putpixel_alpha(J->pixel + j * J->w + i , r, g, b, 0xff);
                     }   
     
                }
     
            }
     
        }
     
     }
     
     return J;
    }
    Images attachées Images attachées  

  4. #4
    Membre confirmé

    Homme Profil pro
    autre
    Inscrit en
    Juillet 2015
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Juillet 2015
    Messages : 176
    Par défaut
    j'ai changé ma fonction (j'ai essayé de corriger sur papier avant d'écrire le code). J'ai modifié certaines opérations. Voici mon résultat. N'ayant aucune connaissance dans le domaine, pouvez vous me dire si l'image ci-dessous se rapproche du résultat normal avec ce filtre?

    qu'obtenez-vous avec ce filtre pour vos propres fonctions? sachant que l'image d'origine est en couleurs.

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     int* laplacien[5*5] = {
      -1, -1, -1, -1, -1,
      -1, -1, -1, -1, -1,
     
      -1, -1, 24, -1, -1,
      -1, -1, -1, -1, -1,
      -1, -1, -1, -1, -1,  
    };
    Images attachées Images attachées  

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 252
    Par défaut Alternatives à un code existant
    Partir d'un code existant c'est à double-tranchant surtout que celui-ci est assez cryptique. I une image et i un int ? J une nouvelle image ? r et rr ? Pourquoi pas rrr ?! Après la logique derrière semble cohérente mais Je vois 3 alternatives :
    • Opter pour une bibliothèque de traitement d'images/calcul scientifique (Comme NumPy et SciPy en Python)
    • Jeter un coup d'œil au code de The GIMP puisque c'est un logiciel libre
    • Coder à partir d'explications/algorithmes afin de se les approprier

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 252
    Par défaut Progrès & pixels parasites
    Tu sembles te rapprocher de l'image de l'article Wikipédia. Pour les pixels parasites c'est peut-être parce qu'il faut borner les composantes. Si le calcul fait plus de 255 ou moins de 0 ça donne n'importe quoi. Désolé je peux pas être plus précis car je connais pas trop de filtre.

  7. #7
    Membre confirmé

    Homme Profil pro
    autre
    Inscrit en
    Juillet 2015
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Juillet 2015
    Messages : 176
    Par défaut
    Je ne veux pas me servir d'une bibliothèque car je voudrais comprendre les rouages du truc.
    Pour mon niveau en maths, il est plutôt nul...

    I est un pointeur de struct nommée "image" dont les champs sont "int w (width), int h (height) et colour* pixel (colour* étant un pointeur d'unsigned char). J'ai repris cette struct des cours de Jacques Olivier Lapeyre, sur youtube.

    J'avais réussi à régler une fonction avec une effet de relief trés réussi, mais j'ai mis le code à la corbeille par inadvertance. Je vais essayer de le retrouver.

Discussions similaires

  1. Comment réaliser cet effet de texte sur une image ?
    Par creale10 dans le forum jQuery
    Réponses: 4
    Dernier message: 25/07/2012, 13h28
  2. Effet de couleur sur une image
    Par icesiiik dans le forum JavaFX
    Réponses: 1
    Dernier message: 26/04/2011, 01h42
  3. [Article] Appliquer un effet de zoom sur une image avec les CSS
    Par Bovino dans le forum Publications (X)HTML et CSS
    Réponses: 1
    Dernier message: 17/10/2010, 07h53
  4. Appliquer un effet de zoom sur une image avec les CSS
    Par Kerod dans le forum Mise en page CSS
    Réponses: 1
    Dernier message: 17/10/2010, 07h53
  5. problème avec un rollover (effet de survol) sur une image/bouton
    Par f56bre dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 19/03/2007, 14h10

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