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

Langage Delphi Discussion :

Recherche occurences couleur pixel


Sujet :

Langage Delphi

  1. #1
    Membre du Club
    Inscrit en
    Août 2006
    Messages
    185
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 185
    Points : 65
    Points
    65
    Par défaut Recherche occurences couleur pixel
    Bonjour a tous,
    j'aimerais trouver le nombre d'occurences de chaque couleur est dans une image... Par exemple 255 255 255 est la couleur de 25 pixels sur l'image, 255 020 001 est la couleur de 230 pixels sur l'image... J'ai vu que l'alghorithme de compression Huffman devait chercher les occurences pour la compression mais les sources delphi que je trouve sur internet sont asser compliquées et la recherche d'occurences est cachée dans le code... J'ai penser faire comme pour la recherche de caractères dans un texte mais en utilisant scanline mais je n'ai pas été trop loin, je pense que cette méthode en utilisant un while serait trop longue, vu qu'il y a 16581375 couleurs différentes... Si quelqu'un a déjà fais quelque chose qui ressemble ou une idée par ou commencer pour avoir de bonnes performances.... Merci d'avance pour vos réponses

  2. #2
    Membre chevronné
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Points : 2 158
    Points
    2 158
    Par défaut
    Niveau performance je ne sais pas trop. Mais scanline sur un TBitmap memoire (sans affichage graphique) est ce qu'il y a de plus rapide avant de passer a des trucs de ouf comme l'asm

    Donc une double boucle for sur With et Height, recuperant les lignes (Scanline) puis les pixels dans cette ligne devrais faire l'affaire.

    Apres pour compter les occuerances j'opterais pour une matrice tri ou quadri dimentionnelle de 0 a 255 pour indexer chaques couleurs.
    Occuerence[R, V, B, A] donne le nombre d'occurence de la couleur definie par [R, V, B, A].
    Acces direct aux occurences, pour les incrementer au fure et a mesure de l'analyse des pixels.

    Pour acceder rapidement aux composantes d'un pixel, il suffit de declarer un Record (ou packed Record) de 4 byte : R, G, B, A.
    Un cast du TColor vers ce type record permet d'acceder separement aux 4 octets qui compose un entier : TColor.

  3. #3
    Membre du Club
    Inscrit en
    Août 2006
    Messages
    185
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 185
    Points : 65
    Points
    65
    Par défaut
    matrice tri ou quadri dimentionnelle de 0 a 255 pour indexer chaques couleurs.
    Occuerence[R, V, B, A] donne le nombre d'occurence de la couleur definie par [R, V, B, A]. ???
    J'ai éssayer avec un tableau array [0..255] of array [0..255] of array [0..255] of integer... il me fais un stack overflow... Cela signifie que le tableau est troo grand??
    Pourrais-tu préciser qu'elle méthode utiliserais-tu pour stocker la couleur de chaque pixel... Merci d'avance

  4. #4
    Membre chevronné
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Points : 2 158
    Points
    2 158
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Type TOccurances = Array[0..255, 0..255, 0..255, 0..255] of Integer;
    Ca devrais marcher ... j'ai deja employer ce mode declaratif pour gerer le calcul alpha d'une image.

  5. #5
    Membre du Club
    Inscrit en
    Août 2006
    Messages
    185
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 185
    Points : 65
    Points
    65
    Par défaut
    J'ai toujours l'erreur stack overflow quand il essait de mettre dans l'array... Pourquoi???

  6. #6
    Membre chevronné
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Points : 2 158
    Points
    2 158
    Par défaut
    a mon avis ca viens d'ailleur.
    Tu n'est pas en recursivité, ou tout autre type de boucle infinie ?

    Poste le code (complet) d'ajout dans le tableau histoire de verifier.
    Mais le probleme ne viens pas de l'ajout en lui meme mais de la maniere dont tu l'effectue.

  7. #7
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Bonjour,

    A toutes fins utiles, voiçi une fonction qui renvoie le nombre total réel de couleurs présentes dans un Bmp et qui est super-rapide raison pour laquelle je la cite il est peut-être possible de la modifier afin qu'elle renvoie le nombre d'occurences de chaque couleur présente dans une image tout en conservant sa rapidité (elle provient du site efg2)
    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
     
    Compter le nombre de couleurs d''une Bmp : SUPER RAPIDE
    =====================================================
    // Count number of unique R-G-B triples in a pf24bit Bitmap.
    //
    // Use 2D array of TBits objects -- when (R,G) combination occurs
    // for the first time, create 256-bit array of bits in blue dimension.
    // So, overall this is a fairly sparse matrix for most pictures.
    // Tested with pictures created with a known number of colors, including
    // a specially constructed image with 1024*1024 = 1,048,576 colors.
    //
    // efg, October 1998.
    FUNCTION CountColors(CONST Bitmap:  TBitmap):  INTEGER;
      VAR
        Flags:  ARRAY[BYTE, BYTE] OF TBits;
        i    :  INTEGER;
        j    :  INTEGER;
        k    :  INTEGER;
        rowIn:  pRGBTripleArray;
    BEGIN
      // Be sure bitmap is 24-bits/pixel
      ASSERT (Bitmap.PixelFormat = pf24Bit);
     
      // Clear 2D array of TBits objects
      FOR j := 0 TO 255 DO
        FOR i := 0 TO 255 DO
          Flags[i,j] := NIL;
     
      // Step through each scanline of image
      FOR j := 0 TO Bitmap.Height-1 DO
      BEGIN
        rowIn  := Bitmap.Scanline[j];
        FOR i := 0 TO Bitmap.Width-1 DO
        BEGIN
          WITH rowIn[i] DO
          BEGIN
     
            IF   NOT Assigned(Flags[rgbtRed, rgbtGreen])
            THEN BEGIN
              // Create 3D column when needed
              Flags[rgbtRed, rgbtGreen] := TBits.Create;
              Flags[rgbtRed, rgbtGreen].Size := 256;
            END;
     
            // Mark this R-G-B triple
            Flags[rgbtRed,rgbtGreen].Bits[rgbtBlue] := TRUE
          END
        END
      END;
     
      RESULT := 0;
      // Count and Free TBits objects
      FOR j := 0 TO 255 DO
      BEGIN
        FOR i := 0 TO 255 DO
        BEGIN
     
          IF   Assigned(Flags[i,j])
          THEN BEGIN
            FOR k := 0 TO 255 DO
              IF   Flags[i,j].Bits[k]
              THEN INC(RESULT);
            Flags[i,j].Free;
          END
     
        END
      END
     
    END {CountColors};
    A+

  8. #8
    Membre chevronné
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Points : 2 158
    Points
    2 158
    Par défaut
    J'ai du mal a comprendre le fonctionnement de cette methode.

    Si j'ai bien compris : Il se base sur un couple R/G et ne cree la 3e composante que si cela est necessaire afin d'accelerer le calcul.

    Dans ce cas, pourquoi ne pas creer seulement un tableau a 1 dimention, don on creera les autre si la composante est presente ? Pourquoi partir sur un tableau a 2 dimention ?

    Sinon, mis a part cette astuce de parcours, la rapiditee de cette fonction ne dois pas trop etre differente de ma version Tri ou Quadri dimentionnelle en adressage direct.

    A la limite pour gagner en rapiditee, pourquoi ne pas utiliser la matrice pour incrementer rapidement les occurances, et gerer un tableau unidimentionnel parrallele pour stocker les couleurs (couple R/G/B/(A)) qui d'un simple parcours de complexité N (ou N est le nombre de couleurs differentes) permettra d'acceder directement aux nombre d'occurances, sans avoir a parcourir toute la matrice ....

    Heuuu yen a encore qui suivent ?!?

  9. #9
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219

  10. #10
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 875
    Points : 11 365
    Points
    11 365
    Billets dans le blog
    6
    Par défaut
    pour un tableau [R,G,B] d'integer : 64 Mo
    pour un tableau avec la transparence : 16 Go

    pas étonnant les débordements de pile !

  11. #11
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 875
    Points : 11 365
    Points
    11 365
    Billets dans le blog
    6
    Par défaut
    c'est pas joli-joli, mais ça va assez vite (2/3 secondes) pour une photo de 4 MPixels, sur mon vieux Pentium III 450 MHz !
    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
    procedure TForm1.Button4Click(Sender: TObject);
    type
      TFrequence=array[Byte,Byte,Byte] of Cardinal;
      PFrequence=^TFrequence;
    var
      Fichier: string;
      bmp_Source: TBitmap;
      S_Origine, i: Cardinal;
      PPixel: ^RGBTriple;
      Frequence: PFrequence;
    begin
      // prend sur le tas (pile limitée à 16 Mo dans mon Delphi 5)
      GetMem(Frequence, SizeOf(TFrequence));
      FillChar(Frequence^, SizeOf(Frequence), 0);
      // initialisation du BitMap
      Fichier:='Photo 001.jpg';
      Image1.Picture.LoadFromFile(Fichier);
      Form1.Refresh;
      bmp_Source:=TBitmap.Create();
      bmp_Source.Assign(Image1.Picture.Graphic);
      // adresse de début de la ligne 0 (qui est à l'adresse la plus élevée)
      S_Origine:=Cardinal(bmp_Source.ScanLine[0]);
      // détermination du bout de cette ligne
      PPixel:=Pointer(S_Origine + 3*bmp_Source.Width);
      // parcours des pixels (adresses décroissantes)
      for i:=0 to bmp_Source.Height*bmp_Source.Width-1 do
      begin
        Dec(PPixel);
        // incrémente la couleur
        Inc(Frequence^[PPixel^.rgbtBlue, PPixel^.rgbtGreen, PPixel^.rgbtRed]);
      end;
      Image1.Picture.Assign(nil);
      Form1.Refresh;
      bmp_Source.Free;
      FreeMem(Frequence, SizeOf(TFrequence));
    end;

  12. #12
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    Citation Envoyé par Sub0 Voir le message
    Comme ce genre de tableau provoque un EStackOverflow, on utilise un tableau d'objet "Bleu" possédant deux dimensions (Rouge et Vert) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Flags: Array[Byte, Byte] Of TBits;
    etc...
    Citation Envoyé par cpdump Voir le message
    Le problème des boolean est qu'ils occupent un octet alors qu'un seul bit est utile.
    J'avais écrit une classe bitfield qui simule un champ de bits de taille quelconque, où chaque flag occupe 1 bit ce qui permet d'économiser 14Mo de mémoire (16 - (16/8))

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

Discussions similaires

  1. Recherche occurences dans formulaire
    Par Laverdure_mt dans le forum Access
    Réponses: 2
    Dernier message: 29/03/2008, 17h54
  2. moteur recherche + code couleur
    Par popofpopof dans le forum IHM
    Réponses: 5
    Dernier message: 28/03/2008, 13h51
  3. Recherche Occurance dans un fichier Txt
    Par spirit daemon dans le forum Débuter
    Réponses: 5
    Dernier message: 29/11/2007, 22h10
  4. Parcours de fichier et recherche occurences
    Par superdj dans le forum Pascal
    Réponses: 20
    Dernier message: 24/07/2007, 11h50
  5. [C#] rechercher occurence sans casse
    Par robocop2776 dans le forum Windows Forms
    Réponses: 2
    Dernier message: 12/09/2006, 15h37

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