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++Builder Discussion :

Problème avec filtre moyenneur "flou uniforme" d’une image


Sujet :

C++Builder

  1. #1
    Membre éclairé Avatar de SmileSoft
    Inscrit en
    Mars 2008
    Messages
    436
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 436
    Par défaut Problème avec filtre moyenneur "flou uniforme" d’une image
    Salut


    Je dois filtrer une image bitmap en niveau de gris par un filtre moyenneur (flou uniforme),vous pouvez voir le résultat de ce filtre dans ce lien: http://xphilipp.developpez.com/artic...s/?page=page_4

    Quand j’ai exécuté mon code l’image en résultat été défectueuse.
    mon code du filtre moyenneur est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     for(i=0;i<=Form1->Image1->Picture->Height-1;i++)
      {
     for( j=0;j<=Form1->Image1->Picture->Width-1;j++)
        {
     Form1->Image2->Canvas->Pixels[i][j]=(Form1->Image1->Canvas->Pixels[i-1][j-1]+Form1->Image1->Canvas->Pixels[i-1][j]+Form1->Image1->Canvas->Pixels[i-1][j+1]+ Form1->Image1->Canvas->Pixels[i][j-1]+ Form1->Image1->Canvas->Pixels[i][j]+Form1->Image1->Canvas->Pixels[i][j+1]+Form1->Image1->Canvas->Pixels[i+1][j-1]+Form1->Image1->Canvas->Pixels[i+1][j]+Form1->Image1->Canvas->Pixels[i+1][j+1])/9;
        }
        }
    je vous joins le résultat de cette exécution comme une image.

    Est ce que quelqu'un peut m'explique pourquoi j'ai pas eu le même résultat qui est donné sur le lien si dessus ??

    Merci d'avance.

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    Pour une raison très simple, en supposant que l'on travaille sur des bitmaps 24 bits,
    - il te faut extraire un composante et une seule, puisque un niveau de gris c'est : R=G=B
    - faire la moyenne sur les 9 points
    - recomposer la teinte qui correspond au niveau de gris (le résultat de la moyenne des 9 points pour R, G et B)
    La plus simple à extraire de (TColor) Couleur est la première (le bleu il me semble) avec un masque : 0xFF

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    TCanvas *C1 = Image1->Picture->Bitmap->Canvas;
    TCanvas *C2 = Image2->Picture->Bitmap->Canvas;
    Byte r;
     
    ...
     
        r = (Byte)(((C1->Pixels[x-1][y-1] & 0xFF) +
                    ...
                    ...
                    (C1->Pixels[x+1][y+1] & 0xFF)) / 9);
     
        C2->Pixels[x][y] = (TColor)(RGB(r,r,r));
    ...
    Si on est dans le contexte des bitmaps 8 bits... alors ça risque de se compliquer si on n'obtient toujours pas le résultat escompté !!!

    Par ailleurs... si la rapidité du traitement a une importance, dans ce cas il faudra utiliser TBitmap::ScanLine.

    A plus !

  3. #3
    Membre émérite Avatar de b_reda31
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 899
    Par défaut
    Bonjour,
    r = (Byte)(((C1->Pixels[x-1][y-1] & 0xFF) +
    ...
    ...
    (C1->Pixels[x+1][y+1] & 0xFF)) / 9);

    C2->Pixels[x][y] = (TColor)(RGB(r,r,r));
    Il est aussi possible d'obtenir une composante (R,G ou B)sans appliquer de masque,juste en utilisant une de ces méthodes GetRValue,GetGValue,GetBValue (Renvoi les composantes R ,G,B respectivement)ce qui donnerai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
    r = (Byte)(((GetRValue(C1->Pixels[x-1][y-1] )) +
                    ...
                    ...
                    (GetRValue(C1->Pixels[x+1][y+1] )) / 9);
     
        C2->Pixels[x][y] = (TColor)(RGB(r,r,r));
    Puisque ici l'image est au niveau de gris les trois composantes on la même valeur.

  4. #4
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    En réalité, le compilateur n'applique pas de masque puisque celà revient précisément à récupérer le LSB du int (ce que BCB sait optimiser lors de la compilation) !
    C'est juste de l'écriture !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define GetRValue(rgb)   ((BYTE) (rgb))
    A plus !

  5. #5
    Membre éclairé Avatar de SmileSoft
    Inscrit en
    Mars 2008
    Messages
    436
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 436
    Par défaut Problème avec filtre moyenneur " flou uniforme" d'une image
    Salut

    Merci pour henderson et b_reda31,

    Avec la solution de henderson, l'image de resultat ne s'affiche pas voici le code que j'ai mis:
    Code : 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
     
    TCanvas *C1 = Image1->Picture->Bitmap->Canvas;
    TCanvas *C2 = Image2->Picture->Bitmap->Canvas;
    Byte r;
     
               for(int x=0;x<=Form1->Image1->Picture->Height-1;x++)
                 {
                   for( int y=0;y<=Form1->Image1->Picture->Width-1;y++)
                    {
    r = (Byte)(((C1->Pixels[x-1][y-1] & 0xFF) + (C1->Pixels[x-1][y] & 0xFF)+(C1->Pixels[x-1][y+1] & 0xFF)+(C1->Pixels[x][y-1] & 0xFF)+(C1->Pixels[x][y] & 0xFF)+(C1->Pixels[x][y+1] & 0xFF)+(C1->Pixels[x+1][y-1] & 0xFF)+(C1->Pixels[x+1][y] & 0xFF)+(C1->Pixels[x+1][y+1] & 0xFF)) / 9);
     
     C2->Pixels[x][y] = (TColor)(RGB(r,r,r))
                    }
                   }
     
    ;
    j'aimerai bien utiliser cette solution des pointeurs pour optimiser le temps de réponse , est ce que j'ai fait des erreurs dans là dessus??
    Avec la solution de b_reda31, le problème est réglé mais le temps de réponse est très long voici le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Byte r;
      for(int x=0;x<=Form1->Image1->Picture->Height-1;x++)
        {
        for( int y=0;y<=Form1->Image1->Picture->Width-1;y++)
        {
    r=(((GetRValue(Image1->Canvas->Pixels[x-1][y-1]) ) +(GetRValue(Image1->Canvas->Pixels[x-1][y]))+(GetRValue(Image1->Canvas->Pixels[x-1][y+1]))+(GetRValue(Image1->Canvas->Pixels[x][y]))+(GetRValue(Image1->Canvas->Pixels[x][y+1]))+(GetRValue(Image1->Canvas->Pixels[x+1][y-1]))+(GetRValue(Image1->Canvas->Pixels[x+1][y+1])) )/ 9);
            Image2->Canvas->Pixels[x][y] = RGB(r,r,r);
             }}
    Merci d'avance

  6. #6
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut

    Désolé, je n'ai pas fait attention !!!

    Remplacer :

    et donc pour éviter les avertissements du compilateur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    (TColor)(RGB( (Byte)r, (Byte)r, (Byte)r))
    La propriété Pixels[X][Y] ne sert qu'à perdre du temps (en fait, non : ça sert à offrir aux utilisateurs préssés un code simple mais qui hélas fait perdre un temps précieux lors de l'exécution) !
    Donc l'optimisation du code nécessite de savoir sur quoi on travaille !
    Bitmap 8 bits ou 24 bits ?

    A plus !

  7. #7
    Membre éclairé Avatar de SmileSoft
    Inscrit en
    Mars 2008
    Messages
    436
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 436
    Par défaut
    Salut henderson

    Code :


    int r;


    et donc pour éviter les avertissements du compilateur :

    Code :


    (TColor)(RGB( (Byte)r, (Byte)r, (Byte)r))
    Le problème persiste toujours, l'image résultante ne s'affiche pas!
    rappelant que j'avais pas d'avertissements du compilateurs.

    et pour :
    l'optimisation du code nécessite de savoir sur quoi on travaille !
    Bitmap 8 bits ou 24 bits ?
    j'utilise une image en niveau de gris donc bitmap 8 bits.
    Est ce qu'il existe d'autres solution

    Merci d'avance

  8. #8
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    On suppose qu'il existe :
    - Image1 en tant que source
    - Image2 en tant que résultat, préalablement chargée avec un bitmap à niveau de gris 8 bits dont la palette est conforme.

    Le traitement ne s'opère que si le bitmap de l'image source a une résulution de 8 bits et si sa palette est cohérente, en terme de niveaux de gris.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    //En global, pour tester la palette
    PALETTEENTRY PaletteEntries[256];
    Code : 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
     
    void __fastcall TForm1::Open1Click(TObject *Sender)
    {
    Graphics::TBitmap *Srce;
    Graphics::TBitmap *Dest = Image2->Picture->Bitmap;
     
    if(OpenPictureDialog1->Execute())
        {
        Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName);
        Srce = Image1->Picture->Bitmap;
        if(Srce->PixelFormat == pf24bit)
            {
            //Je ne montre rien de plus ! 
            }
        else
            {
            if(Srce->PixelFormat == pf8bit)
                {
                //On vérifie la palette de ce bitmap
                //REM : on doit avoir R=G=B=j pour Teintes[j] 
                GetPaletteEntries(Srce->Palette, 0, 256, PaletteEntries);
                for(int j = 0; j < 256; j++)
                    {
                    if((PaletteEntries[j].peRed != j) ||
                       (PaletteEntries[j].peGreen != j) ||
                       (PaletteEntries[j].peBlue != j))
                        {
                        //Je ne montre rien de plus !
                        ShowMessage("Palette non conforme");
                        return;
                        }
                    }
     
                Image2->Width = Image1->Width;
                Image2->Height = Image1->Height;
                Dest->Width = Srce->Width;
                Dest->Height = Srce->Height;
     
                int we = Dest->Width - 1;
                int he = Dest->Height - 1;
     
                Byte *Ym;
                Byte *Y;
                Byte *Yp;
     
                Byte *Dst;
                int r;
     
                for(int y = 1; y < he; y++)
                    {
                    Ym = (Byte*)Srce->ScanLine[y];
                    Y  = (Byte*)Srce->ScanLine[y + 1];
                    Yp = (Byte*)Srce->ScanLine[y + 2];
     
                    Dst = (Byte*)Dest->ScanLine[y + 1];
     
                    for(int x = 1; x < we; x++)
                        {
                        r = (Ym[-1] + *Ym + Ym[1] +
                             Y[-1]  + *Y  + Y[1] +
                             Yp[-1] + *Yp + Yp[1]) / 9;
     
                        Dst[x] = (Byte)r;
     
                        Ym++;
                        Y++;
                        Yp++;
                        }
                    }
                //Comme on a rempli le bitmap
                Image2->Repaint();
                }
            }
        }
    }
    Dans ce code, je n'applique pas le floutage sur les pixels du contour.
    Si on devait pousser jusque là, on sait traiter chacune des 8 zones indépendamment (4 points + 2 lignes + 2 colonnes) en ne tenant compte, pour chacune d'elle, que les pixels qui se trouvent dans l'image.
    Ce faisant, on écarte tout ce qui est pénalisant en terme de temps d'exécution (les tests pour savoir si...).
    Ca ferait du code en plus, ce qui n'est pas grand chose si on recherche vraiment la perfection (peut-être inutilement) !

    A plus !

  9. #9
    Membre éclairé Avatar de SmileSoft
    Inscrit en
    Mars 2008
    Messages
    436
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 436
    Par défaut Problème avec filtre moyenneur "flou uniforme" d’une image
    Salut henderson

    désolez je pose peut être beaucoup de question, Est ce que vous pouvez m'expliquez cette partie:

    Code : 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
    Byte *Ym;
                Byte *Y;
                Byte *Yp;
     
                Byte *Dst;
                int r;
     
                for(int y = 1; y < he; y++)
                    {
                    Ym = (Byte*)Srce->ScanLine[y];
                    Y  = (Byte*)Srce->ScanLine[y + 1];
                    Yp = (Byte*)Srce->ScanLine[y + 2];
     
                    Dst = (Byte*)Dest->ScanLine[y + 1];
     
                    for(int x = 1; x < we; x++)
                        {
                        r = (Ym[-1] + *Ym + Ym[1] +
                             Y[-1]  + *Y  + Y[1] +
                             Yp[-1] + *Yp + Yp[1]) / 9;
     
                        Dst[x] = (Byte)r;
     
                        Ym++;
                        Y++;
                        Yp++;
                        }
                    }
    ?
    même avec cette solution, l'image résultante ne s'affiche pas sachant qu'il n'y a pas d'avertissements/ erreurs du compilateur

    Je vous remercie

  10. #10
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    Dans le code que j'ai donné, il faut raisonner en pré-incrémentation en non en post-incrémentation pour les trois pointeurs (Ym, Y, Yp).

    Voici un autre code, plus lisible peut être.
    REM : Srce et Dest sont deux bitmaps 8 bits ayant les mêmes dimensions.

    Code : 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
     
    int we = Srce->Width - 1; // limite en x exclue
    int he = Srce->Height; // limite en y exclue
     
    Byte *prec = Srce->ScanLine[0];
    Byte *actu = Srce->ScanLine[1];
    Byte *suiv;
    Byte *dst;
     
    for(int y = 2; y < he; y++)
        {
        suiv = (Byte*)Srce->ScanLine[y];
     
        dst  = (Byte*)Dest->ScanLine[y - 1]; 
     
        for(int x = 1; x < we; x++)
            {
            r = (prec[x - 1] + prec[x] + prec[x + 1] +
                 actu[x - 1] + actu[x] + actu[x + 1] +
                 suiv[x - 1] + suiv[x] + suiv[x + 1]) / 9;
     
            dst[x] = (Byte)r;
            }
        //On fait remonter les lignes prec et actu d'une ligne :
        prec = actu;
        actu = suiv;
        //suiv sera chargé par ScanLine
        }
    Ca ne fonctionne évidemment pas sur un bitmap 24 bits et pour le quel il faudrait un code différent !

    A plus !

  11. #11
    Membre éclairé Avatar de SmileSoft
    Inscrit en
    Mars 2008
    Messages
    436
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 436
    Par défaut
    Salut henderson

    Merci pour la nouvelle méthode qui été lisible et optimale, j'ai essayé cette solution et j'avais une erreur du compilateur qui dit:
    [C++ Erreur] Unit1.cpp(52): E2034 Impossible de convertir 'void *' en 'unsigned char *'
    Pour les deux lignes de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Byte *prec = Srce->ScanLine[0];
    Byte *actu = Srce->ScanLine[1];
    Alors j'ai rectifié cette erreur en remplaçant les deux lignes du code par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Byte *prec = (Byte*)Srce->ScanLine[0];
    Byte *actu = (Byte*)Srce->ScanLine[1];
    l'erreur est disparue mais à l'exécution, l'image résultante été blanche.

    donc pas de floutage; voici le code entier pour vérifié:
    Code : 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
    void __fastcall TForm1::BitBtn1Click(TObject *Sender)
    {
    Graphics::TBitmap *Srce;
    Graphics::TBitmap *Dest = Image2->Picture->Bitmap;
    if(OpenPictureDialog1->Execute())
    {Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName);
        Srce = Image1->Picture->Bitmap;
        if(Srce->PixelFormat == pf24bit) {
         ShowMessage("Le bitmap est de 24 bits,Veuillez charger un bitmap 8 bits ");
        }
        else
         {
          if(Srce->PixelFormat == pf8bit)
            {
             //On vérifie la palette de ce bitmap
                //REM : on doit avoir R=G=B=j pour Teintes[j]
                GetPaletteEntries(Srce->Palette, 0, 256, PaletteEntries);
                for(int j = 0; j < 256; j++)
                { if((PaletteEntries[j].peRed != j) ||
                       (PaletteEntries[j].peGreen != j) ||
                       (PaletteEntries[j].peBlue != j))
                        {
                        //Je ne montre rien de plus !
                        ShowMessage("Palette non conforme");
                        return;
                        } }
     
    Image2->Width = Image1->Width;
    Image2->Height = Image1->Height;
    Dest->Width = Srce->Width;
    Dest->Height = Srce->Height;
     
    int we = Srce->Width - 1; // limite en x exclue
    int he = Srce->Height; // limite en y exclue
     
    Byte *prec = (Byte*)Srce->ScanLine[0];
    Byte *actu = (Byte*)Srce->ScanLine[1];
    Byte *suiv;
    Byte *dst;
    int r;
     
     for(int y = 2; y < he; y++)
        {
        suiv = (Byte*)Srce->ScanLine[y];
     
        dst  = (Byte*)Dest->ScanLine[y - 1];
     
        for(int x = 1; x < we; x++)
            {
            r = (prec[x - 1] + prec[x] + prec[x + 1] +
                 actu[x - 1] + actu[x] + actu[x + 1] +
                 suiv[x - 1] + suiv[x] + suiv[x + 1]) / 9;
     
            dst[x] = (Byte)r;
            }
        //On fait remonter les lignes prec et actu d'une ligne :
        prec = actu;
        actu = suiv;
        //suiv sera chargé par ScanLine
     
                }
                //Comme on a rempli le bitmap
                Image2->Repaint();
            }
    }
     
    }
    }
    Je vous joint le résultat de l'exécution.

    Est ce que j'ai fait une erreur là dessus?

    Merci d'avance

  12. #12
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    Je pense que le problème vient de Image2 qui n'a pas été chargée avec un bitmap 8 bits à niveaux de gris (un référentiel de niveaux de gris).
    Oui ? Non ?

    A plus !

  13. #13
    Membre éclairé Avatar de SmileSoft
    Inscrit en
    Mars 2008
    Messages
    436
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 436
    Par défaut
    Salut henderson

    Citation Envoyé par henderson Voir le message
    Salut !

    Je pense que le problème vient de Image2 qui n'a pas été chargée avec un bitmap 8 bits à niveaux de gris (un référentiel de niveaux de gris).
    Oui ? Non ?

    A plus !
    Oui, Merci beaucoup henderson, le problème maintenant est réglé



  14. #14
    Membre éclairé Avatar de SmileSoft
    Inscrit en
    Mars 2008
    Messages
    436
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 436
    Par défaut
    Salut

    Mon problème a été bien résolu sur les images bitmap 8 bits, avec l'aide de henderson, maintenant je cherche à résoudre le problème sur des bitmaps 24 bits

    J'ai essayé le code que vous m'avez donnez henderson, sans le teste sur la conformité de la palette donné par:
    Code : 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
     
    if(Srce->PixelFormat == pf8bit)
                {
                //On vérifie la palette de ce bitmap
                //REM : on doit avoir R=G=B=j pour Teintes[j] 
                GetPaletteEntries(Srce->Palette, 0, 256, PaletteEntries);
                for(int j = 0; j < 256; j++)
                    {
                    if((PaletteEntries[j].peRed != j) ||
                       (PaletteEntries[j].peGreen != j) ||
                       (PaletteEntries[j].peBlue != j))
                        {
                        //Je ne montre rien de plus !
                        ShowMessage("Palette non conforme");
                        return;
                        }
                    }
    Alors que le résultat a été toujours positive càd que le floutage été appliqué.
    Donc j'ai constaté qu'il faut changer le code.


    Est ce que je peut toucher quelque part dans le code pour appliquer un floutage sur les bitmaps 24 bits?
    Ou, il existe un code totalement différent?

    Merci d'avance !

  15. #15
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    Le lissage (moyenne des voisins) à partir des couleurs se fait sur chaque composante (donc R, G et B).
    La sortie sera toujours un bitmap 24 bits (à cause de la palette... d'un 8 bits).
    Le mieux est d'utiliser la classe que j'ai donnée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class jRgb
    {
    public :
    Byte Blue;
    Byte Green;
    Byte Red;
    };
    Par exemple, Srce et Dest sont deux bitmaps 24 bits (PixelFormat = pf24bit)

    Code : 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
     
    int we = Srce->Width-1;
    int he = Srce->Height;
     
    int r;
    int g;
    int b;
     
    jRgb *P = (jRgb*)Srce->ScanLine[0];
    jRgb *L = (jRgb*)Srce->ScanLine[1];
    jRgb *N;
     
    jRgb *T;
     
    for(int y = 2; y < he; y++)
        {
        N = (jRgb*)Srce->ScanLine[y];
        T = (jRgb*)Dest->ScanLine[y-1];
        for(int x = 1; x < we; x++)
            {
            b = (   P[x-1].Blue + P[x].Blue + P[x+1].Blue +
                    L[x-1].Blue + L[x].Blue + L[x+1].Blue +
                    N[x-1].Blue + N[x].Blue + N[x+1].Blue) / 9;
     
            g = (   P[x-1].Green + P[x].Green + P[x+1].Green +
                    L[x-1].Green + L[x].Green + L[x+1].Green +
                    N[x-1].Green + N[x].Green + N[x+1].Green) / 9;
     
            r = (   P[x-1].Red + P[x].Red + P[x+1].Red +
                    L[x-1].Red + L[x].Red + L[x+1].Red +
                    N[x-1].Red + N[x].Red + N[x+1].Red) / 9;
     
            // Sortie vers le bitmap 24 bits
            T[x].Blue = (Byte)b;
            T[x].Green = (Byte)g;
            T[x].Red = (Byte)r;
            }
        P = L;
        L = N;
        }
    Pour un lissage sur des niveaux de gris à partir d'un bitmap 24 bits... au cas où on est certain d'avoir des niveaux de gris, il suffit de calculer la moyenne sur une seule des composantes (puisque R = G = B)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    g = ( P[x-1].Blue + P[x].Blue + P[x+1].Blue +
          L[x-1].Blue + L[x].Blue + L[x+1].Blue +
          N[x-1].Blue + N[x].Blue + N[x+1].Blue) / 9;
    Pour une sortie du niveau de gris vers un 24 bits : REM : jRgb *T

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    T[x].Blue = (Byte)g;
    T[x].Green = (Byte)g;
    T[x].Red = (Byte)g;
    Pour une sortie du niveau de gris vers un 8 bits : REM : Byte *T

    Il faut faire attention avec le bitmap de sortie, s'il s'agit d'un 8 bits.
    Ici, les index (chaque pixel) correspondront avec l'intensité des gris (REM : R = G = B = index).
    Mais si la palette du bitmap est quelconque (R = G = B != index... ou pire... R != G != B != index), la représentation de l'image sera complètement faussée, bien que les niveaux de gris soient justes !
    Puisque la couleur de chaque pixel est donnée par la palette !
    D'où l'intérêt d'utiliser un référentiel de niveau de gris !
    On peut se les préparer assez facilement (référentiels de gris, vert, bleu...) pour les limiter au programme lui-même ou bien pour être mémorisés dans un dossier spécifique.
    Par la suite, une fois faits, il suffit de les charger dans un TImage, lors de la conception...

    Il ne faut pas non plus négliger de lisser les bords !!!
    - pour les 4 coins, on a 4 pixels
    - pour les 4 segments on a 6 pixels
    La sanction arrive assez vite si on lisse une image sur "elle-même" plusieurs fois (pour obtenir le flou artistique très prononcé).
    Lorsque le premier lissage fait apparaître un cadre bien marqué il tend à s'étaler au fil des opérations ... !!!

    A plus !

  16. #16
    Membre éclairé Avatar de SmileSoft
    Inscrit en
    Mars 2008
    Messages
    436
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 436
    Par défaut
    Merci encore une foi henderson

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème avec filtre sur filtre
    Par barbapapa2 dans le forum IHM
    Réponses: 5
    Dernier message: 25/10/2008, 11h14
  2. Problème avec Filtre Blur sur un clip trop large
    Par gobi13 dans le forum ActionScript 1 & ActionScript 2
    Réponses: 0
    Dernier message: 20/01/2008, 23h51
  3. Problème avec filtre d'un formulaire ?
    Par HookerSeven dans le forum Access
    Réponses: 3
    Dernier message: 25/02/2006, 01h59

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