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 :

[D7] Comment faire une comparaison de deux images jpg ?


Sujet :

Langage Delphi

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 5
    Points : 4
    Points
    4
    Par défaut [D7] Comment faire une comparaison de deux images jpg ?
    bonjour a tous !

    Comment faire une comparaison de deux images jpg sous delphi7 ?

    j'aimerai pouvoir avoir un resultat en pourcentage de similarité.

    si vous avez des solutions, des objets a me proposer, ou autres,
    merci.

    Krisk

  2. #2
    Membre confirmé
    Avatar de lil_jam63
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    447
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 447
    Points : 600
    Points
    600
    Par défaut
    Bonjour et bienvenue sur les forums de Developpez.com.

    Tu pourrais par exemple faire une comparaison pixels par pixels ensuite pour le pourcentage de similarité, tu peux le définir en fonction du nombrede pixels comparé et le nombre de pixels différents.
    Je ne pense pas que ce soit la bonne solution, surtout si tes images ne font pas la même taille mais c'est une idée de départ
    ----------------------------------------------------
    Avant de poster, pensez à utiliser les différents outils à votre disposition:
    Google, la FAQ et le moteur de recherche.

  3. #3
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    J'avais justement réfléchi au même problème, et j'étais arrivé à une solution satisfaisante au niveau qualité, mais lourde d'un point de vue performance.

    J'espère que tu es familier avec les termes d'imagerie, sinon ça va être dur à comprendre :
    - Convertir chaque image en niveau de gris.
    - Egaliser l'histogramme.
    - Redimensionner les deux images à une taille commune, qui peut être quelconque (ex : 300x300). L'important est qu'elle soit plus petite, par exemple d'un facteur 2 sur chaque dimension. Utiliser une interpolation pour la réduction : ça permet de supprimer le tramage.
    - Soustraire les deux images.
    - Calculer la moyenne de couleur des pixels de la différence (utiliser un histogramme, c'est plus simple même si c'est un peu plus lent).
    - Si cette valeur est inférieure à un certain seuil (ex : <16), tu peux considérer les images comme identiques.

    Ca marche pour toutes les images, y compris pour comparer une JPEG avec une GIF... Mais le coût en temps de calcul est assez monstrueux.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    488
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 488
    Points : 397
    Points
    397
    Par défaut
    Salut,

    Il n'existe pas de définition précise du degré de similarité de deux images, et il faudrait donc que tu précises dans quel contexte tu te situes pour connaitre les paramètres importants, pour ton application, dans tes images.

    Une méthode générale qui marche assez bien et qui est adaptable au contexte consiste à :
    - prendre des descripteurs d'images (spectre de couleurs, corrélations de couleurs, gradients, Canny, ...)
    - Passer chacun de ces descripteur à travers un réseau de neurones que tu entraines (ou toute fonction similaire qui te permette d'"évaluer" un descripteur).
    - Affecter des poids aux résultats obtenus en fonction de leur importance dans ton contexte (couleurs, textures, formes, ...). Cela peut se faire de façon empirique, ou en entrainant un nouveau réseau.

    Il suffit finalement de mesurer le degré de corrélation entre les résultats obtenus pour chaque image.

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 5
    Points : 4
    Points
    4
    Par défaut
    merci de vos reponses

    j'ai enfin trouver une solution.

    avec l'objet TImageEnView des objets ImageEn

    methode:
    TImageEnView.Proc.CompareWith()

    si vous connaissez mieux ?

    merci a+

    -----------------------------
    Krisk

  6. #6
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Pense alors à cliquer sur en bas à gauche, stp.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 5
    Points : 4
    Points
    4
    Par défaut cet objet est tres lent
    j'ai essayer l'objet precedement cité mais il est tres lent et shareware.

    j'ai beaucoup d'image a comparer et j'ai entendu parler, pour aller plus vite, qu'il falait cree avant une signature suivant des criteres particulier.

    savez vous des choses la dessus ?

    merci
    ------------------------------------------------------
    krisk

  8. #8
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut Re: cet objet est tres lent
    Citation Envoyé par krisk33
    j'ai essayer l'objet precedement cité mais il est tres lent et shareware.
    Pour la lenteur, ça ne m'étonnes absolument pas... Cf. mon premier post.

    Citation Envoyé par krisk33
    j'ai beaucoup d'image a comparer et j'ai entendu parler, pour aller plus vite, qu'il falait cree avant une signature suivant des criteres particulier.
    Oui, mais ça, c'est très bien pour des comparaisons "binaires" (un simple CRC32 fait des merveilles !).
    Mais pour des images, la signature est plutôt volumineuse... J'utilisais comme "signature" une version réduite de l'image (telle que je te l'ai décrite auparavant), mais ça faisait quand même un gros truc (10.000 octets par image environ), et la comparaison "stricte" est impossible.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  9. #9
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 5
    Points : 4
    Points
    4
    Par défaut
    La signature dont j'ai entendu parler et plutot su style de ce que parle sovitec dans son message
    "descripteurs d'images (spectre de couleurs, corrélations de couleurs, gradients, Canny, ...)"

    mais où trouver ces routines mathematiques pour avoir ces informations ?

    ------------------------------------------------------
    krisk

  10. #10
    Membre régulier Avatar de yoghisan
    Profil pro
    Inscrit en
    Février 2004
    Messages
    172
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 172
    Points : 113
    Points
    113
    Par défaut
    Voilà comment je compare des images (de même taille) pour faire un détecteur de mouvement de webcam

    Fonction et procédure utilisées
    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
    procedure TForm1.ComparerBmp(BmpAvant, BmpApres, BmpResult: TBitmap);
    var Bmp: TBitmap;
    begin
      Bmp := TBitmap.Create;
      with Bmp do begin
        Width  := BmpAvant.Width;
        Height := BmpAvant.Height;
        Canvas.CopyMode := CmSrcInvert;
        Canvas.CopyRect(ClientRect, BmpAvant.Canvas, ClientRect);
        Canvas.CopyMode := CmSrcAnd;
        Canvas.CopyRect(ClientRect, BmpApres.Canvas, ClientRect);
      end;
      BmpResult.Assign(Bmp);
      Bmp.Free;
    end;
    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
    function TForm1.BmpLuminosite(Bmp: TBitmap; Niveau: byte): Extended;
    Const MaxPixelCount = 65536; // 65536
    type  TRGBTripleArray = Array[0..MaxPixelCount - 1] Of TRGBTriple;
          pRGBTripleArray = ^TRGBTripleArray;
    var   x, y: integer;
          Ligne: pRGBTripleArray;
          R, G, B, RGB: byte;
    begin
      Result := 0;
      Bmp.PixelFormat := pf24bit;
      for y:=0 to Bmp.Height-1 do begin
        Ligne := Bmp.ScanLine[y];
        For x:=0 to Bmp.Width-1 do begin
          R := Ligne[x].rgbtRed;
          G := Ligne[x].rgbtGreen;
          B := Ligne[x].rgbtBlue;
          RGB := (R+G+B) div 3;
    //      Ligne[x].rgbtRed   := RGB;  // Niveau de gris
    //      Ligne[x].rgbtGreen := RGB;  
    //      Ligne[x].rgbtBlue  := RGB;  
          if RGB>Niveau
            then begin
              Ligne[x].rgbtRed   := 255;  // Blanc
              Ligne[x].rgbtGreen := 255;
              Ligne[x].rgbtBlue  := 255;
              Result := Result+1;
            end
            else begin
              Ligne[x].rgbtRed   := 0;  // Noir
              Ligne[x].rgbtGreen := 0;
              Ligne[x].rgbtBlue  := 0;
            end;
        end;
      end;
      Result := 100*Result/(Bmp.Height*Bmp.Width);
    end;
    BmpCapture et BmpCapturePrecedente sont les images à comparer
    BmpComparaison : image dont les differences apparaissent en blanc
    Régler le niveau acceptable de différence (niveau de la fonction BmpLuminosite)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    //  Image.Picture.Bitmap.Assign(BmpCapture);
      ComparerBmp(BmpCapture,BmpCapturePrecedente,BmpComparaison);
    //  Image.Picture.Bitmap.Assign(BmpComparaison);
      ShapeMouvement.Visible := BmpLuminosite(BmpComparaison,64)>0.1;
    //  Image.Picture.Bitmap.Assign(BmpComparaison);
    C'est assez fluide et tu peux eviter de retourcher : à toi d'adapter ...

    Par exemple mais on peut rien visualiser...
    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
    function TForm1.BmpLuminosite(Bmp: TBitmap; Niveau: byte): Extended;
    Const MaxPixelCount = 65536; // 65536
    type  TRGBTripleArray = Array[0..MaxPixelCount - 1] Of TRGBTriple;
          pRGBTripleArray = ^TRGBTripleArray;
    var   x, y: integer;
          Ligne: pRGBTripleArray;
          R, G, B: byte;
    begin
      Result := 0;
      Bmp.PixelFormat := pf24bit;
      for y:=0 to Bmp.Height-1 do begin
        Ligne := Bmp.ScanLine[y];
        For x:=0 to Bmp.Width-1 do begin
          R := Ligne[x].rgbtRed;
          G := Ligne[x].rgbtGreen;
          B := Ligne[x].rgbtBlue;
          if ((R+G+B) div 3>Niveau) then Result := Result+1;
        end;
      end;
      Result := 100*Result/(Bmp.Height*Bmp.Width);
    end;
    Il faut regler tout ca par la suite

  11. #11
    Membre régulier Avatar de yoghisan
    Profil pro
    Inscrit en
    Février 2004
    Messages
    172
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 172
    Points : 113
    Points
    113
    Par défaut
    Mieux

    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
    function DectectionMouvement(BmpAvant, BmpApres, BmpResult: TBitmap; TraitementBmpResult: Boolean ; Niveau: byte): Extended;
    Const MaxPixelCount = 65536; // 65536
    type  TRGBTripleArray = Array[0..MaxPixelCount-1] Of TRGBTriple;
          pRGBTripleArray = ^TRGBTripleArray;
    var   Blanc: integer;
          x, y: integer;
          LigneAvant, LigneApres, LigneResult: pRGBTripleArray;
          RGBAvant, RGBApres, RGBResult: byte;
    begin
      Blanc := 0;
     
      BmpAvant.PixelFormat  := pf24bit;
      BmpApres.PixelFormat  := pf24bit;
      BmpResult.PixelFormat := pf24bit;
      BmpResult.Width  := BmpAvant.Width;
      BmpResult.Height := BmpAvant.Height;
     
      for y:=0 to BmpResult.Height-1 do begin
        LigneAvant  := BmpAvant.ScanLine[y];
        LigneApres  := BmpApres.ScanLine[y];
        LigneResult := BmpResult.ScanLine[y];
        For x:=0 to BmpResult.Width-1 do begin
          RGBAvant  := (LigneAvant[x].rgbtRed+LigneAvant[x].rgbtGreen+LigneAvant[x].rgbtBlue) div 3;
          RGBApres  := (LigneApres[x].rgbtRed+LigneApres[x].rgbtGreen+LigneApres[x].rgbtBlue) div 3;
          RGBResult := Abs(RGBApres-RGBAvant);
          if RGBResult>Niveau then inc(Blanc,1);
          if TraitementBmpResult then
            if RGBResult>Niveau
              then begin
                LigneResult[x].rgbtRed   := 255;
                LigneResult[x].rgbtGreen := 255;
                LigneResult[x].rgbtBlue  := 255;
              end
              else begin
                LigneResult[x].rgbtRed   := 0;
                LigneResult[x].rgbtGreen := 0;
                LigneResult[x].rgbtBlue  := 0;
              end;
        end;
      end;
     
      Result := 100*Blanc/(BmpResult.Height*BmpResult.Width);
    end;

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

Discussions similaires

  1. [CakePHP] Comment faire une recherche avec deux mots dans une table
    Par pierrot10 dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 12/02/2014, 23h20
  2. [RAM] comment faire une combinaison de deux RAM?
    Par dj_techno dans le forum Composants
    Réponses: 6
    Dernier message: 01/08/2011, 13h44
  3. Comment faire la différence de deux images
    Par souza dans le forum Images
    Réponses: 2
    Dernier message: 09/01/2008, 15h26
  4. Comment faire une classe avec deux form?
    Par Mickey.jet dans le forum Delphi
    Réponses: 10
    Dernier message: 04/07/2006, 18h23
  5. Réponses: 3
    Dernier message: 22/09/2005, 10h34

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