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 :

Acceder aux niveaux de gris d'une image par ScaneLine


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 Acceder aux niveaux de gris d'une image par ScaneLine
    Salut

    Je manipule dans mon application des images en niveau de gris, j’ai codé une fonction nommée Niv2Gris pour transformer l’image chargée en niveau de gris dont le but est de manipuler dans la suite des traitements une seule composante (la composante en niveau de gris que je lui associé la variable (propriété dans la classe TForm1) nommée Gris.

    Voilà le code de la fonction Niv2Gris :

    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
    void __fastcall TForm1::Niv2Gris(Graphics::TBitmap * Srce,TImage *ImgS, Graphics::TBitmap * Dest,TImage *ImgD)
    {
    we = Srce->Width;
    he = Srce->Height;
    P = (jRgb*)Srce->ScanLine[0];
    L = (jRgb*)Srce->ScanLine[1];
    ImgD->Width = ImgS->Width;
    ImgD->Height = ImgS->Height;
     
    for(int y = 2; y < he; y++)
        {
    N = (jRgb*)Srce->ScanLine[y];
    T = (jRgb*)Dest->ScanLine[y-2];
        for(int x = 0; x < we; x++)
            {
     
     Gris = (P[x].Blue + P[x].Green + P[x].Red)/3;
     
    T[x].Blue = (Byte)Gris;
    T[x].Green = (Byte)Gris;
    T[x].Red = (Byte)Gris;
     
     }
        P = L;
        L = N;
     
        }
    ImgD->Repaint();
     
     
            }
     
     
    }
    Au chargement de l’image j’appelle la fonction Niv2Gris:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    if(OpenPictureDialog1->Execute())
    {
     
    Form1->Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName);
    ImgS=Image1;
    ImgD=Image1;
    Srce = Image1->Picture->Bitmap;
    Dest = Image1->Picture->Bitmap;
    Niv2Gris(Srce,ImgS,Dest,ImgD);
    }

    Mon fichier .h contient:
    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
     
    public:		// Déclarations de l'utilisateur
     
    int Gris, he,we ;
    Graphics::TBitmap *Srce;
    Graphics::TBitmap *Dest ;
    TImage *ImgS;
    TImage *ImgD;
     
    class jRgb
    {
    public :
    Byte Blue;
    Byte Green;
    Byte Red;
    };
      jRgb* P;
      jRgb* N;
      jRgb* L;
      jRgb* T;
    maintenant ImgD contient l'image en niveu de gris, je cherche comment acceder aux elements de ImgD (l'image en niveau de gris) par la methode ScaneLine?

    Merci d'avance !

  2. #2
    Membre averti
    Inscrit en
    Avril 2008
    Messages
    76
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 76
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public:		// Déclarations de l'utilisateur
     
    int Gris, he,we ;
    D'apres ce que je lis ici la variable n'est pas globale mais fait partis d'une classe, donc dépentante de l'objet instancié.

  3. #3
    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 !

    Donc... où sont stockés les gris ???

    Comme ici on s'obstine à utiliser un 24 bits pour du niveau de gris et bien, il suffit d'assumer... en récupérant l'une des composantes dans le bitmap de destination... de la même manière qu'on l'aura fait pour le calculer mais en plus simple : soit R, G ou B (puisque R = G = B = gris)!

    Par ailleurs, ton code est sans doute décliné d'un bout code concernant un traitement à l'aide d'une matrice (3*3)... on y trouve donc des pointeurs qui ne servent à rien, ici, pour une conversion en niveaux de gris !

    Je ne suis pas sûr que la déclaration des variables en tant que propriétés aille dans le bon sens !

    A plus !

  4. #4
    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

    Citation Envoyé par Traxsilver Voir le message
    D'apres ce que je lis ici la variable n'est pas globale mais fait partis d'une classe, donc dépentante de l'objet instancié.
    Peut être que j’ai male expliqué en disant que Gris est une variable globale ; j’aurais pu dire que c’est un champ / propriété de la classe TForm1.
    Donc... où sont stockés les gris ???

    .........
    Oui vous avez raison, je n’ai pas une seule variable « Gris » je dois avoir une matrice (de taille de l'image chargée) contenant les gris.


    Puisque ImgD contient l’image en niveau de Gris est ce qu’elle peut me servir (au lieu d’utiliser une matrice pour stocker les gris) ?

    si c'est le cas Comment manipuler cette image par le ScaneLine??

    L’idée des 3 pointeurs été pour se déplacé dans l’image : le pointeur P point sur la ligne actuelle de l’image, L sur la ligne suivante et ainsi de suite, en fait j’ai pris l’idée de floutage ( 3*3).

    Si vous avez d’autre idée merci de me la montrée.



    Merci d'avance!

  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
    salut

    j'ai reformulé mon problème

    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 !

    ScanLine est une propriété de Graphics::TBitmap qui s'applique donc à tout TImage::TPicture::TBitmap et qui renvoie un pointeur sur l'une des lignes du bitmap.

    Donc si le bitmap de destination des niveaux de gris est un 24bits, alors c'est le même schéma algorithmique qu'avec ta conversion.
    Comme dans un 24 bits, les composantes sont égales (R = G = B = gris), suite à cette conversion en niveau de gris, il suffit de n'en récupérer qu'une seule (R, G ou B).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Graphics::TBitmap *Gris24Bits = ImageEn24Bits->Picture->Bitmap;
    Byte gris;
    jRgb *D;
    ...
    D = (jRgb*)Gris24Bits->ScanLine[y];
    ...
    gris = D[x].Blue; // ou Green ou Red puisque R = G = B
    Si ton bitmap de destination des niveaux de gris était un 8 bits, alors dans ce cas le pointeur renvoyé par ScanLine donnerait directement les niveaux de gris.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Graphics::TBitmap *Gris8Bits = ImageEn8Bits->Picture->Bitmap;
    Byte gris;
    Byte *D;
    ...
    D = (Byte*)Gris8Bits->ScanLine[y];
    ...
    gris = D[x];
    REM :
    - un bitmap 24 bits mémorise ses pixels avec les 3 composantes (RGB) d'ou la classe jRgb avec ses trois Bytes.
    - un bitmap 8 bits ne mémorise ses pixels que sous la forme d'un index (du type Byte) auquel correspond une couleur dans sa palette (256 teintes max).
    Cette palette n'est importante que si l'on doit afficher le bitmap car dans ce cas, cette palette devient le référentiel de teintes à partir duquel tous les pixels du bitmap vont se coloriser.

    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

    Merci henderson de me sauver comme d’habitude, une petite question concernant ma fonction Niv2Gris, vous avez dit:

    Citation Envoyé par henderson Voir le message
    Salut !

    ......Par ailleurs, ton code est sans doute décliné d'un bout code concernant un traitement à l'aide d'une matrice (3*3)... on y trouve donc des pointeurs qui ne servent à rien, ici, pour une conversion en niveaux de gris !

    ...
    A plus !
    Est-ce qu’il ya une possibilité de ne pas utiliser 3 pointeurs pour parcourir l’image ?

    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 !

    Le plus évident est, en partant sur la base suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Graphics::TBitmap *Srce;
    int we = Srce->Width
    int he = Srce->Height
    Graphics::TBitmap *Dest;
    Dest->Width = we;
    Dest->Height = he;
    Pour la conversion entre bitmaps 24 bits :

    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
     
    jRgb *S;
    jRgb *D;
    Byte gris;
     
    for(int y = 0; y < he; y++)
        {
        S = (jRgb*)Srce->ScanLine[y];
        D = (jRgb*)Dest->ScanLine[y];
        for(int x = 0; x < we; x++)
            {
            gris = (Byte)( (S[x].Blue + S[x].Green + S[x].Red) / 3 );
            D[x].Blue  = gris;
            D[x].Green = gris;
            D[x].Red   = gris;  
            }
        }
    Si le source devait être un bitmap 8 bits on ne procèderait pas ainsi.
    Par contre dans un programme vite fait (donc mal fait à mes yeux) on trouverait une ligne du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Srce->PixelFormat = pf24bit;
    Pour le convertir d'abord en 24 bits pour ensuite appliquer l'algo précédent de la conversion en niveaux de gris.
    Ce n'est pas la bonne méthode en terme de performances et plus précisément en terme de temps d'exécution !!!

    Si la distination est un 8 bits, dans ce cas l'algo est un peu plus simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    jRgb *S; // source en 24 bits
    Byte *D; // destination en 8 bits
     
    for(int y = 0; y < he; y++)
        {
        S = (jRgb*)Srce->ScanLine[y];
        D = (Byte*)Dest->ScanLine[y];
        for(int x = 0; x < we; x++)
            {
            D[x] = (Byte)( (S[x].Blue + S[x].Green + S[x].Red) / 3 );
            }
        }
    Pour ce dernier cas, si ce bitmap n'est jamais affiché, alors il peut servir uniquement pour les calculs.
    Par contre on risque d'avoir un sacré problème lors de l'affichage (incohérence complète au niveau de l'image) si la palette de ce bitmap n'est pas en niveaux de gris.

    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
    Salut

    je vous remercie infiniment henderson, c'est résolu

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

Discussions similaires

  1. alléger les niveaux de gris d'une image
    Par sifouasma dans le forum Images
    Réponses: 4
    Dernier message: 11/05/2014, 23h01
  2. Réglage des niveaux de gris d'une image
    Par mohamine1989 dans le forum Interfaces Graphiques en Java
    Réponses: 4
    Dernier message: 05/04/2013, 21h59
  3. la moyenne des niveaux de gris d'une image
    Par NGeVtC87 dans le forum Images
    Réponses: 7
    Dernier message: 15/03/2012, 23h46
  4. java extraire les niveaux de gris d'une image
    Par wildthing dans le forum Général Java
    Réponses: 11
    Dernier message: 20/05/2009, 13h41
  5. Réponses: 4
    Dernier message: 05/01/2006, 20h29

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