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 :

Lenteur avec Timage


Sujet :

C++Builder

  1. #1
    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 Lenteur avec Timage
    Bonjour à tous,
    j'ai dans ma forme un Timage contenant une image bmp et je voudrai effectuer plusieurs traitements (Zoom,Transformation en niveau de gris...etc)
    Pour cette image en niveau de gris,voici comment je procéde:


    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
     
    int r,g,b,gris;
    for (i=0;i<Image1->Picture->Width;i++)
    {
    for (j=0;j<Image1->Picture->Height;j++)
    {
    r=GetRValue(Image1->Canvas->Pixels[i][j]);
    g=GetGValue(Image1->Canvas->Pixels[i][j]);
    b=GetBValue(Image1->Canvas->Pixels[i][j]);
     
    gris=(g+g+b)/3;
     
    Image1->Canvas->Pixels[i][j]=RGB(gris,gris,gris);
     
    }
    }
    Ca fonctionne trés bien mais le probléme c'est que ça demande un temps de reponse assez important (Environ 4 secondes pour une image 250X250)

    Quelqu'un aurait une idée pour accélerer le traitement?




    Je tiens à préciser que j 'ai déja poster ce problème dans la rubrique Algorithmique->Traitement d'image (Voir topic )et j'ai été orienté ici

  2. #2
    Membre Expert
    Avatar de Crayon
    Inscrit en
    Avril 2005
    Messages
    1 811
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 811
    Par défaut
    Salut, au lieu d'utiliser Pixels, utilise ScanLine c'est plus rapide.

    Va voir le post suivant:
    http://www.developpez.net/forums/showthread.php?t=17982

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    134
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2006
    Messages : 134
    Par défaut
    slt,

    va voir ce sujet: http://www.developpez.net/forums/sho...d.php?t=339646
    Au post 6 tu as un bon exemple.

  4. #4
    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
    Merci infiniment pour vos réponses.
    J’ai réussi à transformer une image couleur en une image en niveau de gris avec ScanLine et le traitement est beaucoup plus rapide qu’en utilisant Canvas->Pixel[i][j]...Merci encore

    Néanmoins j’aurai besoin de quelques confirmations cette fonction : (Dites moi SVP ou est ce que je me trompe)

    ScanLine(y) renvoi un vecteur (pointeur vers vecteur).Ce vecteur contient le code des couleurs de la ligne « y » de l’image.
    Pour ce qui est de la taille de ce vecteur, là est le problème ; J’utilise dans mon application des images « bmp format 24bits ».Prenons l’exemple d’une image (100*100) pixels
    En exécutant :

    ptr = (Byte *)bmp->ScanLine[0];


    La taille du vecteur de « ptr » sera de 3*100 n’est ce pas ? (Car chaque couleur nécessite 3 bytes)
    Ptr[0] vaut le niveau de ROUGE ( R ) du premier pixel de l’image.
    Ptr[1] vaut le niveau de VERT ( G ) du premier pixel de l’image.
    Ptr[2] vaut le niveau de BLEU ( B ) du premier pixel de l’image.


    Est-ce bien cela ?





    Si oui :
    Dans le cas ou l’utilisateur ouvre une image bmp 256 couleurs (1Byte par couleur)
    La taille du vecteur Ptr sera donc égal à la largeur de l’image ? ( et non pas 3*largeur)
    Dans ce cas comment rendre cette image en niveau de gris ?
    J’ai pensé à transformer cette image en une image 24bits en dupliquant chaque pixel 3 fois pour les 3 composantes (RGB) mais cela ne me parait pas très optimale.

  5. #5
    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
    alors personne pour m'aider?

  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 !

    On suppose en particulier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    //Pour les 8 bits
    Graphics::TBitmap *Bitmap = new Graphics::TBitmap;
    PALETTEENTRY Colors[256];
    int GreyLevels[256];
     
    // Récupérer le chemin d'un dossier
    AnsiString Filepath;
    Ainsi qu'une classe pour les 24 bits:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class jPixel
    {
    public :
    Byte Blue;
    Byte Green;
    Byte Red;
    };
    Dans le constructeur de la form :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Filepath = ExtractFilePath(Application->ExeName);
    //On suppose l'existence d'un bitmap référence 8 bits en niveau de gris
    Bitmap->LoadFromFile(Filepath + "GreyRef.bmp");
    La méthode qui va calculer les niveaux de gris en tenant compte du pixelformat du bitmap.

    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
     
    void __fastcall TForm1::Greylevels1Click(TObject *Sender)
    {
    jPixel *Pixel;
    Byte *Srce, *Dest;
    int grey, Start, blue, red, green, c1;
    Graphics::TBitmap *B = Image1->Picture->Bitmap;
     
    switch(B->PixelFormat)
        {
        case pf8bit :
        //Couleurs disponibles pour cette image
        GetPaletteEntries(B->Palette, 0, 256, Colors);
        //Niveaux de gris correspondants
        for(int j = 0; j < 256; j++)
            {
            GreyLevels[j] = ((Colors[j].peRed * 30) +
                             (Colors[j].peGreen * 59) +
                             (Colors[j].peBlue * 11)) / 100;
            }
     
        //Transfert des indexes de srce à dest
        Bitmap->Width = B->Width;
        Bitmap->Height = B->Height;
        for(int y = 0; y < B->Height; y++)
            {
            Srce = (Byte*)B->ScanLine[y];
            Dest = (Byte*)Bitmap->ScanLine[y];
            for(int x = 0; x < B->Width; x++)
                {
                Dest[x] = (Byte)GreyLevels[ Srce[x] ];
                }
            }
        //On assigne le bitmap à celui de l'image
        //Ce qui affecte également la palette de l'image
        Image1->Picture->Bitmap->Assign(Bitmap);
        break;
     
        case pf24bit :
        Start = GetTickCount(); //pour mesurer le temps
        for(int y = 0; y < B->Height; y++)
            {
            Pixel = (jPixel*)B->ScanLine[y];
            for(int x = 0; x < B->Width; x++)
                {
                //Non optimisé :
                grey = ((Pixel[x].Red * 30) +
                        (Pixel[x].Green *59) +
                        (Pixel[x].Blue *11)) / 100;
     
                Pixel[x].Red = (Byte)grey;
                Pixel[x].Green = (Byte)grey;
                Pixel[x].Blue = (Byte)grey;
                }
            }
        //Pour faire écho du temps passé
        ShowMessage(IntToStr(GetTickCount() - Start));
     
        //Par contre, il faut rafraîchir l'image
        Image1->Repaint();
        break;
        }
    }
    On peut éventuellement optimiser la multiplication par des constantes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    c1 = Pixel[x].Red;
    red = (c1 << 5) - c1 - c1;
     
    c1 =  Pixel[x].Green;
    green = (c1 << 6) - (c1 << 2) - c1;
     
    c1 = Pixel[x].Blue;
    blue = (c1 << 4) - (c1 << 2) - c1; 
     
    // à optimiser sans doute (je n'ai pas le temps de me souvenir)
    grey = (red + green + blue) / 100;
    Cette optimisation n'apporte que peu de gain, chez moi, 7 à 8 ms sur les 175 ms pour une image 640 * 480.
    Ca devient forcément sensible sur un flux de traitement !

    J'ai supposé que l'on devait faire écho des niveaux de gris.
    Pour des traitement en arrière plan, il suffira donc de supprimer tout ce qui intervient dans le mise en oeuvre de cet écho.

    Ne pas oublier non plus de libérer le bitmap :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
    {
    delete Bitmap;
    Bitmap = NULL;
    }

    Voilà voilà... A plus !

  7. #7
    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
    Oops…Désolé du retard !
    Merci infiniment Henderson . Je ne connaissais pas la propriété « PixelFormat »
    Grâce à celle-ci mon problème est résolu.

    Envoyé par henderson
    Ne pas oublier non plus de libérer le bitmap
    à quoi cela servitait il?

  8. #8
    Membre Expert
    Avatar de Crayon
    Inscrit en
    Avril 2005
    Messages
    1 811
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 811
    Par défaut
    Habituellement avant de fermer un programme tu es toujours mieux de libéré tout ce qui est en mémoire. C'est une bonne pratique

    Si ton problème est résolu n'oublie pas de mettre un petit

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

Discussions similaires

  1. Probleme de lenteur avec Netbeans 5.5
    Par sachet dans le forum NetBeans
    Réponses: 5
    Dernier message: 02/07/2008, 16h28
  2. problème de lenteur avec BO
    Par darwini dans le forum Débuter
    Réponses: 2
    Dernier message: 13/04/2007, 14h08
  3. Problème de lenteur avec 2 sous-formulaires
    Par picatchou dans le forum Access
    Réponses: 1
    Dernier message: 29/01/2007, 08h48
  4. pb de lenteur avec Index
    Par LeNeutrino dans le forum MS SQL Server
    Réponses: 11
    Dernier message: 19/12/2006, 11h48
  5. [Débutant] Lenteur avec TComPort
    Par PhDt76 dans le forum C++Builder
    Réponses: 22
    Dernier message: 27/09/2003, 21h43

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