⚠️ Ceci est un site de traduction non officiel, sans lien avec ImageMagick Studio LLC. Pour des informations officielles, consultez la page originale (https://usage.imagemagick.org/compare/index.html).

Exemples ImageMagick -- Comparaison d'images

Exemples ImageMagick, préface et index
Méthodes de comparaison d'images -- qu'est-ce qui diffère ?

Méthodes de comparaison d'images

Le programme Compare

Le programme « magick compare » est fourni pour vous offrir un moyen simple de comparer deux images similaires, afin de déterminer à quel point elles sont « différentes ». Par exemple, j'ai ici deux images d'un « sac » animé, que j'ai ensuite passées à « magick compare » pour mettre en évidence les zones où il a changé.

  magick compare bag_frame1.gif bag_frame2.gif  compare.gif

[IM Output] [IM Output] [IM Output]

Comme vous pouvez le voir, vous obtenez une image blanche et rouge, qui contient une « ombre » de la seconde image. Elle montre clairement les trois zones qui ont changé entre les deux images. Plutôt que d'enregistrer l'image « compare », vous pouvez bien sûr la visualiser directement, ce que je trouve plus pratique, en produisant la sortie vers le format spécial « [x:](files.html#x) », ou en utilisant le programme « [display](basics.html#display) ». Par exemple…

  magick compare bag_frame1.gif bag_frame2.gif  x:
  magick compare bag_frame1.gif bag_frame2.gif  miff:- | display

Depuis IM v6.4, vous pouvez changer la couleur des différences du rouge vers une autre couleur plus intéressante… |

  magick compare bag_frame1.gif bag_frame2.gif \
          -highlight-color  SeaGreen  compare_color.gif

[IM Output]
Depuis IM v6.4.2-8, vous pouvez également spécifier l'autre couleur. |

  magick compare bag_frame1.gif bag_frame2.gif \
          -highlight-color  SeaGreen  -lowlight-color PaleGreen \
          compare_colors.gif

[IM Output]
Si vous ne voulez pas de cette « ombre » de la seconde image, depuis IM v6.4.2-8 vous pouvez ajouter un « -compose src » aux options pour la supprimer. |

  magick compare bag_frame1.gif bag_frame2.gif \
          -compose Src compare_src.gif

[IM Output]
En utilisant les trois réglages supplémentaires, nous pouvons générer un masque en niveaux de gris des pixels modifiés… |

  magick compare bag_frame1.gif bag_frame2.gif \
          -compose Src -highlight-color White -lowlight-color Black \
          compare_mask.gif

[IM Output]
Notez toutefois que ce masque concerne N'IMPORTE quelle différence, même la plus infime. Par exemple, vous pouvez voir toutes les différences mineures produites par l'enregistrement d'une image au format JPEG avec pertes

  magick bag_frame1.gif  bag_frame1.jpg
  magick compare bag_frame1.gif bag_frame1.jpg   compare_lossy_jpeg.gif

[IM Output] [IM Output] [IM Output]

Comme vous pouvez le voir, même si vous ne distinguez pas vraiment de différence entre les versions GIF et JPEG de l'image, « magick compare » signale un grand nombre de différences. En utilisant un petit facteur de flou (fuzz), vous pouvez demander à IM d'ignorer ces différences mineures entre les deux images. |

  magick compare -metric AE -fuzz 5% \
          bag_frame1.gif bag_frame1.jpg   compare_fuzz.gif

[IM Text]

[IM Output]
Cela montre que la plupart des différences réelles ne sont que mineures. Le réglage spécial « [-metric](https://imagemagick.org/command-line-options/#metric) » avec la valeur « AE » (abréviation de « Absolute Error », le décompte de l'erreur absolue) signale (sur la sortie d'erreur standard) le nombre réel de pixels qui ont été masqués au facteur de flou courant.

Images de différence

Pour avoir une meilleure idée de la façon exacte dont les images diffèrent, il vaut probablement mieux obtenir une image de composition « [difference](compose.html#difference) » plus précise… |

  magick composite bag_frame1.gif bag_frame1.jpg \
            -compose difference  difference_jpeg.gif

[IM Output]
Comme vous pouvez le voir, alors que « magick compare » a montré que le JPEG créait beaucoup de différences entre les images, une composition « [difference](compose.html#difference) » était assez sombre, indiquant que toutes les différences étaient relativement mineures. Si l'image résultante paraît trop noire pour voir les différences, vous pouvez normaliser l'image (en utilisant le « [-auto-level](https://imagemagick.org/command-line-options/#auto-level) » mathématiquement plus correct), afin d'accentuer le résultat. |

  magick difference_jpeg.gif  -auto-level  difference_norm.gif

[IM Output]
Cela montre encore que la plupart des différences restent très mineures, la plus grande différence se produisant le long des bords nets de l'image, que le format de fichier JPEG ne gère pas très bien. En revanche, obtenir une image de différence entre les deux images d'origine de l'animation révèle des différences très marquées entre les deux images, même sans aucune accentuation. |

  magick composite bag_frame1.gif bag_frame2.gif \
            -compose difference  difference_frames.gif

[IM Output]
Notez que, la méthode de composition « [difference](compose.html#difference) » étant associative, l'ordre des deux images dans les exemples ci-dessus n'a pas d'importance. Toutefois, contrairement à « magick compare », vous pouvez comparer des images de tailles différentes, l'image de destination déterminant alors la taille finale de l'image de différence. La méthode difference est encore plus utile lorsqu'elle est employée avec le programme « magick », car vous pouvez traiter davantage l'image résultante avant d'enregistrer ou d'afficher le résultat. Par exemple, vous pouvez appliquer un seuil à chacun des canaux de couleur puis les fusionner pour générer un masque de tout pixel ayant changé de couleur entre les deux images. |

  magick bag_frame1.gif bag_frame2.gif -compose difference -composite \
          -threhold 0 -separate -evaluate-sequence Add \
          difference_mask.gif

[IM Output]
C'est essentiellement ce que fait le programme « magick compare », mais avec davantage de contrôle sur la couleur et le style de sortie. Cependant, comme vous pouvez le constater, il a tendance à détecter jusqu'au plus petit changement entre deux images. Si les images proviennent d'un format de fichier avec pertes, tel que JPEG, ou d'une image GIF ayant nécessité une réduction de couleurs et un tramage (quantification des couleurs), alors il détecterait probablement tout dans l'image. À ce titre, ce n'est généralement pas très utile. Pour de meilleurs résultats, vous pouvez essayer de déterminer à quel point les couleurs des pixels diffèrent réellement. Par exemple, nous pouvons convertir le résultat en niveaux de gris, afin d'obtenir une meilleure image de comparaison qu'une image colorée. |

  magick bag_frame1.gif bag_frame2.gif -compose difference -composite \
          -colorspace Gray   difference_gray.gif

[IM Output]
Ici, contrairement à « magick compare », l'image de différence montre un mélange des deux images combinées dans le résultat final. Regardez par exemple l'étrange « talisman » qui semble apparaître sur le front du chat. Il s'agissait à l'origine de la poignée du sac de la première image. Cette fusion peut rendre confus ce que vous voyez exactement comme différences, car vous voyez un mélange des ajouts et des suppressions de l'image. En raison de cette confusion des détails, « magick compare » est généralement la meilleure méthode pour nous, humains, tandis que l'image de « différence » est la meilleure méthode pour un traitement ultérieur de l'image. Toutefois, convertir une image de différence en niveaux de gris ne fait que moyenner (en réalité par une moyenne pondérée) les distances RVB. Par conséquent, une différence de couleur d'un seul bit pourrait être perdue à cause des effets d'arrondi quantique. Si même la plus petite différence entre les images est importante, une meilleure méthode consiste à additionner séparément les canaux de couleur de l'image de différence, afin de garantir la capture de TOUTES les différences, y compris la plus infime. |

  magick bag_frame1.gif bag_frame2.gif -compose difference -composite \
          -separate -evaluate-sequence add   difference_add.gif

[IM Output]
La valeur de différence produite ci-dessus est connue sous le nom de métrique de « distance de Manhattan ». C'est-à-dire la distance entre les deux couleurs de chaque image lorsque vous êtes restreint à un déplacement orthogonal (ou axial). Attention toutefois : de grandes différences peuvent être écrêtées (ou brûlées), car elles peuvent dépasser la « plage quantique » (Quantum Range) des données de pixel, ou les limites des entiers, à moins d'utiliser une version HDRI d'IM. Pour aller plus loin, vous pouvez obtenir la distance vectorielle des couleurs, en utilisant des carrés et des racines carrées pour implémenter une distance pythagoricienne ou euclidienne. |

  magick bag_frame1.gif bag_frame2.gif -compose difference -composite \
           -evaluate Pow 2 -separate -evaluate-sequence Add -evaluate Pow 0.5 \
           difference_vector.gif

[IM Output]
C'est en fait similaire à ce que mesure réellement un facteur de « flou » dans le cadre de son seuillage (lorsqu'aucune transparence n'est en jeu). Cependant, le « flou » divise aussi les valeurs au carré par 3 avant de les additionner, afin de garantir que le résultat ne dépasse pas les limites de la plage de couleurs de l'image. Cela signifie que vous n'obtiendriez un pixel purement « blanc » dans le résultat que pour la différence entre des couleurs primaires et secondaires opposées, comme entre un pixel bleu et un pixel jaune. Alors, appliquons aussi cette mise à l'échelle… |

  magick bag_frame1.gif bag_frame2.gif -compose difference -composite \
          -evaluate Pow 2 -evaluate divide 3 -separate \
          -evaluate-sequence Add -evaluate Pow 0.5 \
          difference_vector_scaled.gif

[IM Output]
C'est en réalité très similaire à ce que vous obtiendriez pour une image de différence « -colorspace Gray » (comme ci-dessus), mais c'est une représentation beaucoup plus précise de la différence de couleur. Vous pourriez omettre la seconde opération « Pow 0.5 », auquel cas vous obtiendriez une image de différence au carré. Il existe d'autres métriques de distance de couleur, que vous pouvez découvrir sur la page Color Difference, Wikipedia. La plupart d'entre elles impliquent de générer des différences vectorielles (voir la dernière) mais en utilisant un espace colorimétrique différent, tel que LAB ou LUV. Cela serait toutefois plus important pour comparer des différences de couleur du monde réel (par exemple, des mesures de différence de la vision humaine). Voyez également la suppression d'arrière-plan, où des images de différence comme celles ci-dessus servent à effectuer la suppression d'arrière-plan. Vous pouvez aussi jeter un œil à cette page externe sur la détection de changement comme exemple pratique de son utilisation.

Comparaison par scintillement

Une alternative au programme « magick compare » pour voir les différences entre des images consiste à effectuer une comparaison par scintillement entre les images similaires, à un rythme raisonnablement rapide. |

  magick -delay 50 bag_frame1.gif bag_frame2.gif -loop 0 flicker_cmp.gif

[IM Output]
Pour faciliter cela, j'ai écrit un script qui affiche une animation de deux images données, appelé « **[flicker_cmp](../static/img/scripts/flicker_cmp)** », qui bascule entre les deux images, exactement comme dans l'exemple ci-dessus. Il ajoute aussi une étiquette au bas de l'image affichée, afin de préciser quelle image vous voyez à un instant donné.

Comparaison d'animations

Vous pouvez également comparer les différences entre deux animations fusionnées (coalesced) au moyen d'une technique spéciale de « bande de film ». Voyez une technique d'« append » similaire dans Assemblage côte à côte. Pour l'essentiel, nous assemblons toutes les images de l'animation pour former une seule grande et longue image. Les deux images sont ensuite comparées, et une nouvelle animation est créée en redécoupant l'animation en images séparées. Par exemple…

    magick \( anim1.gif -coalesce -append \) \
            \( anim2.gif -coalesce -append \) miff:- | \
      magick compare - miff:- |\
        magick - -crop 160x120 +repage anim_compare.gif

Le résultat est une animation des images de « comparaison », produisant une version « atténuée » de la seconde animation, superposée à une surbrillance montrant les parties qui diffèrent. Notez que, pour que cela fonctionne, la taille du « [-crop](https://imagemagick.org/command-line-options/#crop) » doit correspondre à la taille d'origine de l'animation. De plus, l'animation perdra tous les délais variables qu'elle aurait pu avoir, utilisant un délai constant fondé sur la première image de l'animation d'origine. Une autre technique de comparaison d'images utile pour les animations sert à localiser toutes les zones où une animation change, afin de diviser les parties non connectées de l'animation. Vous pouvez ainsi séparer une grande animation en plusieurs animations plus petites. Voyez Découper une animation.


Statistiques de comparaison

À quel point deux images diffèrent-elles ?

En cours de construction

Statistiques à partir d'une image de différence…

  Ce qui suit produit des informations détaillées et extrait uniquement la
  section contenant les statistiques de canal de l'image….

    magick image1 image2 -compose Difference -composite \
            -colorspace gray -verbose  info: |\
       sed -n '/statistics:/,/^  [^ ]/ p'

  Les nombres entre parenthèses (s'ils sont présents) sont des valeurs
  normalisées entre zéro et un, indépendantes du niveau Q de votre IM.
  Si vous n'avez pas ces nombres, envisagez de mettre à jour votre IM.

  Pour obtenir le niveau de gris moyen (mean) en pourcentage, vous pouvez
  utiliser cette commande…

     magick image1 image2 -compose Difference -composite \
           -colorspace gray -format '%[fx:mean*100]' info:

  Pour une valeur non exprimée en pourcentage, encore plus simple…

     magick image1 image2 -compose Difference -composite \
           -colorspace gray -format '%[mean]' info:


Statistiques du programme Compare…

   Vous pouvez obtenir une valeur de différence moyenne réelle en utilisant -metric

     magick compare -metric MAE image1 image2 null: 2>&1

   Ajouter -verbose fournira des informations plus précises sur chaque canal
   séparé.

      magick compare -verbose -metric MAE rose.jpg reconstruct.jpg null: 2>&1

      Image: rose.jpg
      Channel distortion: MAE
        red: 1884 (0.028748)
        green: 1532.34 (0.023382)
        blue: 1691.25 (0.0258068)
        all: 1702.53 (0.025979)

   Il existe plusieurs métriques différentes parmi lesquelles choisir.
   Avec le même ensemble d'images de test (pour la plupart identiques)

   Nombre de pixels
      AE ...... Décompte de l'erreur absolue (Absolute Error) du nombre de pixels différents (0=égal)

                Cette valeur peut être seuillée à l'aide d'un réglage -fuzz pour
                ne compter que les pixels dont l'écart dépasse le seuil.

                Depuis IM v6.4.3, le décompte -metric AE est affecté par -fuzz.
                Vous pouvez ainsi écarter les différences « mineures » de ce décompte.

                magick -metric AE -fuzz 10% image1.png image2.png null:

                Quels pixels sont différents peut être vu à l'aide de l'image
                de sortie (ignorée dans la commande ci-dessus).

                C'est la SEULE métrique qui soit affectée par le « fuzz ».

   Erreur maximale (d'un seul pixel)
      PAE ..... Erreur absolue de crête (Peak Absolute Error) (dans un canal, pour un espace colorimétrique 3D)
      PSNR .... Rapport signal sur bruit de crête (Peak Signal to noise ratio) (utilisé dans les articles sur la compression d'images)
                Le rapport de la différence quadratique moyenne à la valeur
                quadratique moyenne maximale pouvant exister entre deux images,
                exprimé en décibels.

                Plus le PSNR est élevé, plus les images sont proches, une
                différence maximale se produisant à 1. Un PSNR de 20 signifie
                que les différences sont de 1/100 du maximum.

   Erreur moyenne (sur tous les pixels)
      MAE ..... Erreur absolue moyenne (Mean absolute error) (distance d'erreur moyenne par canal)
      MSE ..... Erreur quadratique moyenne (Mean squared error) (distance d'erreur au carré moyennée)
      RMSE .... Racine de l'erreur quadratique moyenne -- c.-à-d. : sqrt(MSE)


   Métriques spécialisées
      MEPP .... Erreur moyenne normalisée ET erreur maximale normalisée
                Pour les images sans transparence, elles devraient être
                directement liées au facteur « -fuzz ».

                Avec de la transparence, cela devient difficile : le masque
                devrait affecter le nombre de pixels comparés, et donc la
                « moyenne », mais ce n'est pas fait actuellement.

      FUZZ      différence de facteur de flou tenant compte de la transparence

      NCC       corrélation croisée normalisée (1 = similaire)

   J'ai obtenu les résultats suivants sur mes images de test…

    _metric_|__low_Q_jpeg__|__black_vs_white__
     PSNR   | 29.6504      | 0
     PAE    | 63479        | 65535
     MAE    | 137.478      | 65535
     MSE    | 4.65489e+06  | 4.29484e+09
     RMSE   | 2157.52      | 65535


   La première colonne de nombres est une comparaison d'images présentant des
   différences dues à un JPEG de basse qualité, où l'image de test a été lue
   puis réenregistrée avec un réglage -quality très bas.

   La seconde, « black vs white », est une comparaison d'une image noire unie
   avec une image blanche unie. Si la « couleur moyenne » de l'image est
   ignorée par la comparaison, la valeur résultante sera très faible. Cela ne
   semble être le cas qu'avec la métrique PSNR, toutes les autres ayant produit
   une valeur de différence maximale.

   Le e+06 est la notation scientifique, indiquant de combien de rangs décaler
   la virgule. Par ex. :   4.65489e+06  -->  4,654,890.0
   Cela équivaut donc à environ 4 millions, et c'est le carré de 2157.52.

   ATTENTION : les nombres dépendent des niveaux de qualité (Q) d'IM fixés à la
   compilation. Plus la qualité est élevée, plus les nombres sont grands. Seul
   le PSNR ne devrait pas en être affecté. Pour cette raison, IM fournit aussi
   un résultat « normalisé » non affecté par le réglage de qualité de
   compilation, bien qu'il puisse garder de légers effets d'arrondi quantique.

   Je n'ai PAS déterminé s'il existe des options « -define » existantes
   utilisables avec la fonction « compare ».


   NOTE : pour les couleurs opaques, les distances AE -fuzz et RMSE sont
   équivalentes. TOUTEFOIS, lorsque des couleurs transparentes sont en jeu, le
   test du facteur de flou AE traitera deux couleurs entièrement transparentes
   différentes comme identiques, tandis que RMSE les traitera comme différentes !

   Par exemple…
   Pour AE, le blanc et le noir entièrement transparents sont identiques.

     magick compare -metric AE xc:#0000 xc:#FFF0 null:
     0 (0)

   Pour RMSE, ce sont la même couleur puisqu'ils sont entièrement transparents.

     magick compare -metric RMSE xc:#0000 xc:#FFF0 null:
     0 (0)

Dissimilarity-threshold (seuil de dissimilarité)

  Si vous obtenez une erreur « too different » (trop différent), désactivez-la avec…
      -dissimilarity-threshold 1.0

  Mais qu'est-ce que ce seuil ?

Pour plus d'informations, voyez mes très anciennes notes en texte brut… Image Comparing, Tower of Computational Sorcery


Correspondance de sous-images et de formes

En cours de construction

Utilisation de l'option « compare -subimage-search »…

  magick compare -subimage-search  large_image.png  sub-image.png  results-%d.png

  Cela produit deux images
    results-0.png
        qui affiche l'emplacement correspondant
    results-1.png
        qui est une carte des emplacements possibles du coin supérieur gauche,
        montrant à quel point la sous-image correspond bien à cet emplacement.

  Notez que la seconde image est plus petite, car elle ne concerne que les emplacements
  du coin supérieur gauche. Sa taille est donc large_image - small_image + 1

  La recherche repose toutefois sur une différence de vecteurs de couleur,
  elle produit donc une comparaison de couleurs très précise.

  La recherche effectue essentiellement une comparaison de la petite image à CHAQUE emplacement
  possible dans l'image plus grande. À ce titre, elle est lente ! **très très lente.**.

  La meilleure idée est de comparer une très très PETITE sous-image pour trouver
  les emplacements possibles, puis d'utiliser cela pour effectuer une comparaison de
  différence à chaque emplacement possible afin d'obtenir une correspondance plus précise.

  Jetez un œil au script
    ../static/img/scripts/overlap
  et à la discussion associée
    [Overlapped Images](https://magick.imagemagick.org/viewtopic.php?f=1&t=22526&p=95286)
  qui s'intéresse à la localisation de sous-images à « haute entropie » d'une
  image afin de trouver des correspondances possibles dans une seconde image,
  pour découvrir le décalage de recouvrement et fusionner les images en une plus grande.

  Une autre discussion utilise des recherches de sous-images pour trouver des
  motifs de pavage dans de plus grandes images, afin de générer des images pavables
    [Stitching image over a canvas](https://magick.imagemagick.org/viewtopic.php?f=1&t=22860)


  Exemple utilisant RMSE et la nouvelle fonction -grayscale pour fusionner les
  résultats des canaux de différence de couleur séparés en une image finale

    magick large_image.png small_image.png miff:- |
      magick compare -metric RMSE -subimage-search - miff:- |
        magick - -delete 0 -grayscale MS show:


Seuil de similarité (Similarity Threshold)

  Bien souvent, on ne s'intéresse qu'à la première correspondance trouvée. Dès
  qu'une « bonne » correspondance est trouvée, il n'est pas nécessaire de
  continuer à en chercher une autre. Le -similarity-metric définit ce que vous
  considéreriez comme une bonne correspondance.

  Un « -similarity-threshold 0.0 » s'interrompra à la toute première correspondance « parfaite
  » trouvée, tandis qu'un « -similarity-threshold 1.0 » (la valeur par défaut) ne correspondra
  jamais et explorera chaque point possible. Une valeur intermédiaire fixe un facteur de « flou »
  portant uniquement sur la couleur pour ce que vous jugeriez être une correspondance acceptable.

  Notez que si la recherche de sous-image est interrompue, la seconde image
  « carte » ne contiendra qu'un résultat partiel, ne montrant les résultats que
  jusqu'au point où la comparaison a interrompu sa recherche.


Quelques exemples de base de recherche de sous-image….

  Prenez une capture d'écran d'une fenêtre de terminal (« screen.png »),
  et découpez l'image d'une seule lettre ou d'un seul mot (« letter.png »).

  Signaler uniquement la première correspondance… pour la vitesse,
  interrompre immédiatement après avoir trouvé cette première correspondance.
  Ne pas se soucier de produire les résultats d'image incomplets.

     magick compare -subimage-search -metric AE -similarity-threshold 1.0 \
                   screen.png letter.png null: 2>&1

  NOTEZ que la vitesse dépendra fortement de l'endroit de l'image où cette
  première correspondance est trouvée.

  Trouver toutes les occurrences exactes de cette image,
  sous forme d'image (points blancs sur les correspondances, noir ailleurs)

     magick compare -subimage-search -metric AE \
                   screen.png letter.png miff:- 2>/dev/null |
       magick - -delete 0 show:

  Extraire une liste des coordonnées de toutes les lettres correspondantes (points
  blancs) (sous forme de liste de pixels énumérés, en ignorant tout ce qui est noir)

     magick compare -subimage-search -metric AE \
                   screen.png letter.png miff:-  2>/dev/null |
       magick - -delete 0 txt:- | grep -v '#000000'

  Uniquement la liste des coordonnées

     magick compare -subimage-search -metric AE \
                   screen.png letter.png miff:-  2>/dev/null |
       magick - -delete 0 txt:- | sed -n '/#FFFFFF/s/:.*//p'



Solutions de recherche de sous-image hors ImageMagick…

  « visgrep » du paquet « xautomation ».

    Il s'agit d'un programme de recherche de sous-image bien plus simple, qui ne produit qu'une
    liste de coordonnées pour les correspondances (voire pour plusieurs sous-images). Parce qu'il
    est bien plus simple (pour une correspondance quasi exacte) et qu'il n'essaie pas de générer
    des « images de résultat » pour une étude ultérieure, il est aussi BEAUCOUP PLUS RAPIDE.

    Par exemple…

      visgrep screen.png letter.png

    Résultats chronométrés
      en utilisant « compare » pour obtenir juste la première correspondance   0.21 seconde
      en utilisant « compare » pour obtenir une « image de résultat »           1.56 seconde
        idem, mais en extrayant la liste des coordonnées                        1.76 seconde
      en utilisant « visgrep » pour obtenir toutes les coordonnées correspondantes    0.09 seconde



Autres méthodes de recherche de sous-image….

Morphologie HitAndMiss

  Il s'agit essentiellement d'une correspondance binaire, où vous définissez
  quels pixels doivent être de l'« arrière-plan » et lesquels doivent être de
  l'avant-plan. Elle vous permet toutefois aussi de définir des zones où le
  résultat, avant-plan ou arrière-plan, vous est indifférent.

  C'est fondamentalement une méthode de recherche de motif binaire.

Correlate (une variante de Convolve)

  C'est similaire à Hit and Miss mais en utilisant des valeurs de niveaux de gris.
  Des valeurs positives pour l'avant-plan et négatives pour l'arrière-plan, et
  zéro pour l'indifférent. C'est toutefois limité aux images en niveaux de gris.

  Voyez [Corrélation et recherche de forme](convolve.html#correlate_search).

  Toutes deux sont fondamentalement aussi lentes que la comparaison de
  sous-image précédente, mais moins précises pour ce qui est des couleurs.
  Cependant, leur capacité à spécifier une forme (zones indifférentes) pour la
  sous-image les rend utiles comme méthode de recherche.

  Il vous faut toutefois convertir la sous-image en un « noyau », ou tableau de
  valeurs en virgule flottante, plutôt qu'en une image réelle.


FFT Convolve (NCC)

  La transformée de Fourier rapide est un opérateur lent, mais généralement
  plusieurs ordres de grandeur plus rapide que les deux méthodes précédentes.
  La raison en est qu'une convolution dans le domaine fréquentiel n'est qu'une
  multiplication directe pixel par pixel.

  La méthode « Convolve » peut être convertie en « Correlate » simplement en
  faisant pivoter la sous-image recherchée de 180 degrés.
  Voyez [Correlate](convolve.html#correlate).

  Fondamentalement, en convertissant les images dans le domaine « fréquentiel », vous pouvez
  effectuer une recherche de sous-image très très rapidement par rapport aux méthodes précédentes,
  surtout avec de plus grandes sous-images qui peuvent avoir la même taille que l'image d'origine !

  Je crois que cela a été ajouté sous la forme d'une métrique de comparaison NCC.


<a id="peak_finding"></a>
Recherche et extraction de pics (pour les correspondances partielles proches)…

  Une fois l'image comparée, vous disposerez typiquement d'une sorte de « carte
  de probabilité » qui définit à quel point la correspondance était « parfaite ».

  Ce que vous voulez faire maintenant, c'est trouver la meilleure correspondance, ou
  peut-être plusieurs correspondances dans l'image. Autrement dit, vous voulez localiser
  les principaux « pics » dans la carte résultante et en extraire les emplacements réels.

  * Utiliser un noyau de convolution laplacien

    Pour obtenir des résultats, vous devez trouver les « pics » de l'image, pas
    nécessairement les points les plus lumineux. Vous pouvez les obtenir en
    convoluant l'image de façon à soustraire la moyenne des pixels environnants
    du pixel central. Comme nous ne voulons que des résultats positifs, un
    biais supprime les résultats négatifs.

      magick mandril3_ncc1.png \
              -bias -100% -convolve Laplacian:0 result.png

    En appliquant un seuil et en l'utilisant comme masque, nous pouvons extraire uniquement ces pixels.

      magick mandril3_ncc1.png \
              \( +clone -bias -100% -convolve Laplacian:0 -threshold 50% \) \
              -compose multiply -composite \
              txt:- | grep -v black

    Le problème est que vous pouvez obtenir un amas de points à un pic, plutôt
    qu'un pixel bien défini, en particulier pour deux pixels de pic entourés de
    valeurs très basses.

  * Utiliser un noyau de morphologie Hit and Miss « Peaks »

      magick mandril3_ncc1.png \
              -morphology HMT Peaks:1.5 result.png

    Le problème est que cela peut ne produire aucun résultat si vous obtenez deux pixels de
    pic ayant exactement la même valeur (aucun écart entre l'avant-plan et l'arrière-plan).

    Il existe toutefois d'autres noyaux de « pic » qui localiseront quand même
    un tel amas de pics.

  * Dilater et comparer

    Dilatez (étendez les valeurs maximales) l'image 3 fois puis comparez-la à
    l'image d'origine. Tout pic situé dans la zone de la taille du noyau de
    dilatation (carré de 7 pixels) conservera la même valeur. Mettez à zéro
    tous les pixels qui présentent une différence.

    Méthode de HugoRune (sujet de discussion IM 14491)

  * Correspondance et suppression en boucle.

    Fondamentalement, trouvez la valeur de pixel la plus élevée, notez-la.
    Masquez ensuite tous les pixels d'une zone autour de ce pic, et répétez
    jusqu'à atteindre une certaine limite (nombre de points ou seuil).

    Voyez une implémentation en script shell de cela dans le script de Fred
    Weinhaus « [maxima](http://www.fmwconcepts.com/imagemagick/maxima/) ».

    Cela ne cherche pas à trouver le centre d'un grand « amas » de pixels de
    valeurs presque égales, mais ce serait très rare dans des images réelles.

  * Localisation sous-pixellique

    Si le pic n'est pas un pixel exact, mais pourrait concevablement être un
    emplacement sous-pixellique (entre les pixels), alors une forme de
    correspondance de motif (ajustement de courbe gaussienne) dans la zone du
    pic peut vous permettre de localiser le pic à une coordonnée sous-pixellique.

    Cela peut être plus important dans le recalage d'images pour l'assemblage
    panoramique, en particulier lorsque vous n'utilisez pas un grand nombre de
    points pour obtenir une moyenne au mieux de la superposition en perspective.

  * Trouver un motif de pavage dans une image

    Lorsque vous avez tous les points, une recherche d'un motif répétitif
    (distances vectorielles similaires entre plusieurs pics) devrait révéler
    une forme de structure de pavage.


Améliorer la correspondance de sous-image…

  Le principal problème de Correlate (ou du FFT correlate rapide, qui est la
  même chose) est qu'il n'a absolument aucune compréhension de la couleur.

  La corrélation (ou la convolution) est une technique purement mathématique
  utilisée sur un ensemble de valeurs. Avec les images, cela signifie qu'elle
  n'est appliquée qu'aux canaux individuels d'une image, et NON aux distances
  vectorielles de couleur.


  Alors que compare effectue une véritable comparaison de vecteurs de couleur. Cela
  trouve les formes mieux que correlate, mais c'est beaucoup beaucoup plus lent.

  À ce titre, pour tirer pleinement parti de correlate, vous devriez traiter vos images (au
  préalable pour la vitesse, ou ensuite sur les résultats) afin d'essayer de mettre en évidence
  les différences de couleur de l'image sous forme d'image de « corrélation » en niveaux de gris.

  À NOTER : utiliser -channel pour limiter les opérations à un seul canal de niveaux
  de gris améliorera la vitesse. Dans IMv7, la mise en niveaux de gris réduit les
  images à un seul canal, ce qui permet d'obtenir automatiquement des gains de vitesse.

  Par exemple, au lieu de l'intensité, vous pouvez obtenir une meilleure
  différenciation avant-plan / arrière-plan en extrayant la teinte (Hue) d'une
  image. Mais vous devrez peut-être faire pivoter les teintes s'il y a beaucoup
  de rouge dans la sous-image recherchée.

  Voyez les exemples de séparation de canaux HSL et HSB pour observer
  ce problème. https://usage.imagemagick.org/color_basics/#separate

  Une autre méthode de mise en niveaux de gris qui devrait très bien fonctionner
  consiste à effectuer une détection de contours sur les deux images. Cela met
  en évidence les frontières et la forme, ce qui est typiquement bien plus
  important que tout dégradé lisse ou changement de couleur dans l'image.

  Pour des exemples de méthodes de détection de contours, voyez
    https://usage.imagemagick.org/convolve/#edgedet

  Vous pouvez aussi vous intéresser à la détection de contours directionnelle, de type boussole.

  Fondamentalement, tout ce qui met en valeur la forme dans votre cas particulier
  est une bonne idée. Appliquez-le simplement aux DEUX images avant de les corréler.


Correspondance invariante à l'échelle et à la rotation…

  * indépendance de position…
  * correspondance d'une sous-image pivotée (indépendante de l'angle)
  * correspondance de sous-images redimensionnées (indépendante de la taille)
  * indépendance à la fois de la taille et de l'angle


--------------

Autres correspondances d'images plus spécifiques…

Correspondance de lignes…

  Algorithme de Hough

Correspondance de cercles…

  Variante de l'algorithme de Hough

Correspondance de visages

  Une combinaison de ce qui précède.

Trouver les images en double

Fichiers identiques

Les fichiers sont-ils identiques au niveau binaire, c'est-à-dire s'agit-il exactement du même fichier, probablement de simples copies exactes l'un de l'autre ? Aucun ImageMagick requis. Ne négligez pas cela. Vous pouvez comparer un grand nombre de fichiers très très rapidement de cette manière. La meilleure méthode que j'aie trouvée consiste à utiliser des sommes de contrôle MD5.

  md5sum * | sort | awk {'print $2 " " $1'}  | uniq -Df 1

Et cela listera les md5 des images qui sont identiques. En utilisant cette technique, j'ai créé des scripts capables de générer et de comparer des listes md5sum de fichiers, en renvoyant les fichiers dont le md5 est identique. Notez toutefois que toute modification d'un fichier image autre qu'une copie directe sera classée par cela comme différente, même si les données d'image elles-mêmes sont identiques. Il suffit d'un changement de date ou d'une autre différence mineure de métadonnées dans le fichier pour que l'image soit considérée comme différente.

Signatures d'image IM

Vous pouvez faire générer par IM une « signature » pour chaque image…

  magick identify -quiet -format "%#" images...

Cela génère une chaîne de hachage semblable à ce que produisent MD5 et SHA256. Toutefois, contrairement à ces derniers, elle utilise les données d'image réelles pour générer la signature, et non les métadonnées de l'image. Ainsi, si vous avez deux copies de la même image mais avec des horodatages de création/modification différents, vous devriez obtenir la même signature pour les deux fichiers, alors que MD5 et SHA256 produiraient deux signatures même si l'image elle-même est identique. ATTENTION : lire puis écrire une image JPEG générera des données d'image différentes, et donc une signature différente. Cela est simplement dû à la compression avec pertes qu'utilise le format d'image JPEG.

Comparaison directe

Vous pouvez comparer directement deux images (à l'aide du programme « magick compare ») si elles sont de la même taille, pour voir à quel point elles correspondent. (Voir plus haut) C'est très lent et, d'après mon expérience, pas très utile lorsqu'on l'applique à une image de taille réelle, tant c'est lent. C'est toutefois probablement la meilleure façon de se faire une idée de la similitude réelle de deux images.

Classification des images

Dans mes tentatives de comparaison d'images, j'ai constaté que les images en couleur, de type dessin animé, et les croquis se comparent tous très différemment les uns des autres. Les dessins au trait et les images en niveaux de gris tendent en particulier à présenter de plus petites différences que les images en couleur, avec pratiquement toutes les méthodes de comparaison. Fondamentalement, comme les couleurs sont toutes alignées, toute métrique de couleur tend à placer de telles images 3 fois plus proches les unes des autres (espace colorimétrique unidimensionnel contre espace colorimétrique tridimensionnel). En clair, cela signifie que séparer vos images en au moins ces deux groupes peut être une première étape très importante dans toute tentative sérieuse de trouver des images en double ou très similaires. D'autres classifications majeures ou types d'images peuvent aussi faciliter la comparaison, simplement en réduisant le nombre d'images auxquelles vous vous comparez. Voyez la classification d'images ci-dessous.

Comparaison de vignettes

Vous faites créer par un programme (en mémoire) un grand nombre de petites vignettes (disons 64x64 pixels) des images à comparer pour y chercher des doublons, ce que vous faites ensuite par comparaison directe. C'est typiquement la première chose que les gens (moi y compris) tentent de faire, et c'est en fait la technique qu'emploient la plupart des programmes de comparaison d'images (comme les logiciels de gestion de photos). En réalité, cela fonctionne bien et trouve les images qui correspondent exactement. De plus, avec un peu de flou et un assouplissement du seuil de différence, cela peut même trouver des images qui ont été légèrement rognées et redimensionnées. Toutefois, tenter de stocker en mémoire 10 000 vignettes de ce type provoquera souvent le début d'un emballement (thrashing) sur un ordinateur normal, le rendant très lent. Sinon, stocker toutes ces vignettes (à moins que le programme ne le fasse pour l'affichage à l'utilisateur) consomme beaucoup d'espace disque. Une méthode pour atténuer le problème d'emballement du disque consiste à n'avoir qu'un plus petit nombre d'images en mémoire. C'est-à-dire, comparer les images par groupes, plutôt qu'une image à toutes les autres. Un regroupement naturel se fait par répertoire, en comparant chaque répertoire d'images avec d'autres répertoires d'images. C'est en fait plutôt bon, car les images tendent à être regroupées ensemble, et ce groupe d'images correspondra souvent à un groupe similaire. Produire les images correspondantes par paires de répertoires est ainsi un bonus. Par ailleurs, le degré de similitude acceptable entre deux images dépend de leur type d'image. Comparer deux dessins au trait nécessite un « seuil » très petit pour écarter les images qui diffèrent, tandis que comparer des images comportant de grandes zones de couleur nécessite souvent un seuil bien plus grand pour attraper des images similaires qui ont été rognées. Les images du monde réel posent un plus gros problème : une texture peut produire une différence additive très sérieuse entre des images présentant un très léger décalage. Pour cette raison, vous devrez peut-être simplifier de telles images en zones générales de couleur, soit en utilisant des filtres médians, du flou, une réduction de couleurs, ou une segmentation de couleur. Après un tel traitement, une image du monde réel peut généralement être comparée d'une manière similaire aux dessins animés.

Métriques d'image

Créer une petite métrique pour chaque image est une opération d'ordre linéaire (O). Alors que comparer toutes les images avec toutes les autres est une opération d'ordre quadratique (O^2). Une métrique n'est pas destinée à trouver réellement les images correspondantes, mais à regrouper les images similaires (susceptibles de correspondre) de telle sorte que vous puissiez effectuer une comparaison plus intensive sur des groupes plus petits. À ce titre, toute comparaison de métriques devrait être indulgente et accepter les images ayant une faible probabilité (mais tout de même une probabilité) de correspondance. Mais elle ne devrait pas être indulgente au point d'inclure trop de fausses correspondances. Vous pouvez aussi envisager plusieurs métriques, car certaines métriques peuvent apparier des images qu'une autre métrique « rate de peu », parce qu'elles tombent dans des régions voisines différentes (fausse correspondance de seuil). Dans la section suivante (Métriques) figurent plusieurs métriques différentes générées par IM que j'ai expérimentées, ou théorisées, notamment : couleur moyenne, couleur prédominante, avant-plan/arrière-plan, couleurs de contour, matrice de couleurs, etc. Günter Bachelier a également signalé les possibilités d'utiliser des métriques plus exotiques pour la comparaison d'images, telles que : descripteurs de Fourier, dimensions fractales, aires convexes, longueurs et angles des grand/petit axes, rondeur, convexité, enroulement, solidité, variances de forme, direction, nombres d'Euler, descripteurs de frontière, courbure, énergie de flexion, courbure absolue totale, aires, centre géométrique, centre de masse, compacité, excentricité, moments autour du centre, etc., etc. Mon effort actuel consiste à générer et utiliser une simple matrice 3x3 de moyennes de couleurs pour représenter l'image (voir la métrique de matrice de couleurs ci-dessous). Au fur et à mesure qu'elles sont générées (ou demandées), la métrique est mise en cache (avec d'autres informations de fichier) dans des fichiers spéciaux de chaque répertoire. Ainsi, je n'ai besoin de régénérer une métrique particulière que lorsqu'aucune métrique en cache n'est disponible, ou que l'image a changé.

Similitude ou distance

Les métriques de deux images (ou les images elles-mêmes) peuvent être comparées à l'aide de plusieurs méthodes différentes, produisant généralement une mesure de distance unique ou « métrique de similitude » qui peut servir à regrouper les images « similaires ».

  • Seuil direct, ou différence maximale (distance de Tchebychev)
    Comparez simplement les images par la plus grande différence sur une seule métrique.
    Le seuil produira un hypercube d'images similaires dans l'espace de métriques multidimensionnel. Bien sûr, la différence d'image ne repose que sur une seule métrique et non sur l'ensemble des métriques.
  • Différence moyenne (distance moyenne, distance de Manhattan moyennée)
    Additionnez toutes les différences et, éventuellement, divisez par le nombre de métriques.
    On l'appelle aussi la distance de Manhattan entre deux métriques, car elle équivaut à la distance à parcourir pour se déplacer dans une grille urbaine. Toutes les métriques contribuent également, ce qui fait apparaître les choses « plus proches » que prévu. Dans l'espace, un seuil de cette métrique produira une forme de losange.
  • Différence euclidienne (pythagoricienne)
    Ou la distance vectorielle directe entre les métriques dans l'espace de métriques.
    La valeur tend à être plus grande lorsque davantage de métriques sont en jeu. Toutefois, une métrique produisant une grande différence tend à contribuer plus que les autres. Un seuil produit un volume sphérique dans l'espace de métriques.
  • Erreur mathématique/ajustement de données ou (moment d'inertie ???)
    Additionnez tous les carrés de toutes les différences, puis prenez la racine carrée.
    On l'utilise plus typiquement pour calculer à quel point une courbe mathématique s'ajuste à un ensemble de données précis, mais elle peut aussi servir à comparer des métriques d'image.
    Elle semble fournir la meilleure mesure de distance non vectorielle.
  • Angle de vecteur
    Trouvez l'angle entre les deux droites partant du centre de l'espace vectoriel créé par la métrique des images. Cela devrait supprimer tout effet de contraste ou d'amélioration d'image ayant pu être appliqué aux deux images.
    Reste à tester
  • Distance vectorielle
    Pour les images qui sont des dessins au trait ou des images en niveaux de gris, où tous les vecteurs de couleur individuels d'une métrique sont dans la même direction, les distances relatives des métriques par rapport à la couleur moyenne de l'image sont probablement plus importantes. Normaliser les distances par rapport à la plus grande distance peut réduire l'effet du contraste.
    Autrement dit, c'est une méthode de comparaison d'images de dessin au trait.
    Reste à tester
  • Analyse par grappes (cluster)
    Toutes les métriques sont représentées et regroupées en grappes similaires au sein de l'espace multidimensionnel. Un bon logiciel de regroupement pourrait même être capable de découvrir et d'écarter les métriques qui ne produisent aucun regroupement.
    Reste à tester

Pour l'instant, je constate que la technique de l'« erreur mathématique » semble bien fonctionner à la fois pour les métriques de niveaux de gris et de couleur, en utilisant une simple « métrique de matrice de couleurs » 3x3 moyennée (voir ci-dessous).

Vérification humaine

Une fois que l'ordinateur a terminé ses tentatives de trouver les images correspondantes, c'est à l'utilisateur de vérifier réellement que les images correspondent. Présenter les correspondances à l'utilisateur peut aussi être une tâche difficile, car il voudra probablement pouvoir…

  • Voir les images côte à côte
  • Basculer très très rapidement entre deux images, à leur taille d'origine et, éventuellement, à une taille « mise à l'échelle » commune.
  • Basculer entre, ou superposer, des images différemment mises à l'échelle et translatées, pour tenter de les faire correspondre.
  • Voir d'autres images du même répertoire (source) ou peut-être de la même grappe (autres correspondances proches) que l'image correspondante, afin de traiter un groupe entier plutôt que chaque image individuellement.
  • Renommer, déplacer, remplacer, supprimer, copier les images entre les deux répertoires (ou plus), pour trier les images et en rejeter d'autres.
  • et ainsi de suite…

. Actuellement, je regroupe les correspondances en ensembles et j'utilise une combinaison de programmes pour les traiter sous le contrôle de l'utilisateur. Ces programmes incluent « magick display » et « magick montage » d'IM, ainsi que les visionneuses d'images « XV » et « GQview ». Je reste toutefois ouvert à d'autres suggestions de programmes capables d'ouvrir simultanément deux répertoires ou plus, et d'afficher des collections ou des groupes d'images provenant de plusieurs répertoires. Le contrôle à distance ou par d'autres programmes ou scripts peut être vital, car il permet de configurer et de présenter les groupes d'images de la meilleure façon pour que l'utilisateur les examine et les traite. Aucun programme n'a encore répondu à mes besoins. Par exemple, « gqview » propose des collections et une vue à répertoire unique, mais ne permet pas les vues à répertoires multiples, ni le contrôle à distance / en ligne de commande de la présentation. De plus, les collections n'indiquent pas de quel répertoire provient chaque image, et ne permettent pas de basculer la vue à répertoire unique vers un autre répertoire. Il n'a pas non plus de contrôle à distance. En revanche, le très ancien « xv » permet les vues à répertoires multiples (grâce à plusieurs fenêtres « visual schnauzer ») et une liste de collection dans sa fenêtre de contrôle, mais on ne peut visualiser qu'une image à la fois, et un seul répertoire peut être ouvert et positionné depuis sa ligne de commande. Bien sûr, il n'a pas non plus de contrôle à distance. Ce sont les meilleurs programmes de vérification humaine que j'aie trouvés, que je lance à l'aide d'un script pour chaque groupe d'images, paires correspondantes, ou toutes les images correspondantes d'un groupe. Mais aucun n'est vraiment satisfaisant. Une table lumineuse et le logiciel associé me semblent la meilleure méthode pour trier les images, mais il faut pour cela de plus grands écrans tactiles, ce qui entraîne de grandes dépenses.

Comparaison d'images de types croisés

L'une des choses les plus difficiles que j'aimerais faire est de trouver les images créées à partir d'une autre image. Par exemple, j'aimerais apparier un dessin au trait que quelqu'un a colorié, ou peint, pour produire des images de type dessin animé, voire ultra réalistes. Un arrière-plan peut aussi avoir été ajouté. Ces choses sont très difficiles, et mes expériences avec les techniques de détection de contours n'ont jusqu'à présent pas été concluantes. Trouver la bonne métrique est ici la clé, car les humains peuvent bien mieux établir le lien de « similitude », mais il faut tout de même trouver des correspondances possibles à présenter à l'utilisateur.

Résumé de la recherche d'images en double

En résumé, ma procédure actuelle pour trouver et traiter les images en double est un pipeline de programmes destiné à trouver et trier les images « similaires ».

   Générer/mettre en cache les types d'images et les métriques
     -> Comparer les métriques et regrouper les images.
       -> comparer les images d'une grappe pour trouver des correspondances
         -> regrouper en ensembles d'images correspondantes (par répertoire source)
           -> vérification humaine

Comme vous pouvez le voir, j'envisage une approche fortement étagée. Envoyez-moi vos idées par e-mail !!!


Trier les images par type

Déterminer de quel type d'image il s'agit est important, car la plupart des méthodes de comparaison d'images ne fonctionnent que pour un type d'image précis. Il ne sert à rien de comparer une image de texte avec un croquis d'artiste, par exemple. Il n'est pas non plus utile d'employer une méthode de comparaison d'images en couleur sur une image presque entièrement blanche (croquis). Généralement, la première chose à faire lors de la comparaison d'images est de déterminer de quel type d'image, ou « espace colorimétrique », l'image relève. Les classifications de base des images peuvent inclure…

  • Dessin au trait ou image de texte en noir et blanc (presque entièrement d'une seule couleur)
  • Images composées de deux couleurs de base - à parts égales (images à motifs ?).
  • Dessins d'artiste en niveaux de gris (beaucoup de nuances)
  • Images en couleur linéaire (les couleurs forment un dégradé, mais pas du noir au blanc)
  • Image en couleur de type dessin animé avec de grandes zones de couleurs unies.
  • Une image du monde réel avec des zones de couleurs nuancées
  • L'image contient du texte annoté ou une superposition de logo. (un unique pic de couleur)

Après avoir défini les catégories de base, vous pouvez aussi tenter de trier les images à l'aide de diverses métriques d'image, telles que… * Couleur moyenne de l'image entière * couleur prédominante de l'image * Couleur d'avant-plan/d'arrière-plan de l'image.

Pire encore : les images JPEG ou redimensionnées présentent souvent aussi une distorsion des couleurs, rendant de telles classifications bien plus difficiles, car les couleurs ne seront pas tout à fait celles qu'elles devraient être. Les gris ne seront pas des gris purs, et les lignes ne seront peut-être pas nettes et claires. Une discussion de long terme sur le tri des images par type se trouve sur le forum des utilisateurs d'IM… How to check image color or black and white.

Images en niveaux de gris

La façon la plus simple de vérifier si une image est en niveaux de gris est d'examiner les niveaux de saturation des couleurs de l'image. Cela se fait facilement en convertissant l'image dans un espace colorimétrique « Hue » (teinte) et en obtenant les valeurs moyenne et maximale du canal de couleur (typiquement le vert). Par exemple…

  magick rose: granite: -colorspace HCL \
          -format '%M  avg=%[fx:mean.g] peak=%[fx:maxima.g]\n' info:

[IM Text]

Les nombres sont normalisés dans une plage de 0 à 1. Comme vous pouvez le voir, la « rose » est très colorée (30 % de moyenne), avec un fort pic (proche de 1). L'image « granite » présente en revanche une saturation très faible (2 % environ) et une valeur de pic basse. Bien qu'elle ne soit pas purement en niveaux de gris, elle en est très proche. Une moyenne basse et un pic élevé indiqueront de petites plages de couleur intense. Appliquer un seuil sur le même canal permet de générer un masque des zones colorées de l'image. PROBLÈME : ce qui précède ne détecte pas les images qui sont linéaires en couleur. C'est-à-dire les images qui ne contiennent que des couleurs formant un dégradé de couleur linéaire, comme des photos jaunies (sépia) ou des plans (blueprints). Ce sont essentiellement des images en niveaux de gris colorées. Voyez le type d'image suivant.

L'image est-elle en couleur linéaire

Une autre technique consiste à effectuer un « meilleur ajustement » direct d'une droite tridimensionnelle sur toutes les couleurs (ou une matrice de couleurs simplifiée de métriques) de l'image. L'erreur de l'ajustement (généralement la moyenne des carrés des erreurs) vous donne une très bonne indication de la façon dont l'image s'ajuste à cette droite. L'ajustement d'une droite à l'image tridimensionnelle implique généralement un certain calcul vectoriel. Le résultat vous dira non seulement si l'image utilise un ensemble de couleurs quasi « linéaire », mais il fonctionne pour TOUTE échelle de couleurs, pas seulement du clair au sombre, mais aussi des lignes gris-cassé sur du papier jauni. Le résultat peut aussi servir à convertir l'image en une image « niveaux de gris » plus simple (ou simplement à convertir un ensemble de métriques de couleur en métriques de niveaux de gris) pour des comparaisons plus simples et une meilleure recherche de correspondances. Mon programme de test d'essai n'utilise même pas l'image entière pour effectuer cette détermination, mais fonctionne à l'aide d'une simple métrique de matrice de couleurs ci-dessous, de 9 couleurs (27 valeurs) pour représenter l'image. Attention toutefois : ce test ne distingue généralement pas très bien les dessins au trait non nuancés. De telles images sont presque entièrement d'une seule couleur d'arrière-plan (typiquement le blanc) et, à ce titre, peuvent ne montrer aucune forme de dégradé de couleur linéaire. Elles devraient être séparées au préalable à l'aide d'un test différent (voir ci-après, c'est en fait bien plus facile). Écrivez-moi si cela vous intéresse, et faites-moi savoir ce que vous avez essayé.

Images en noir et blanc purs

Pour voir si une image est presque purement en noir et blanc, avec peu de couleur, ou même de gris (dus à l'anticrénelage), nous pouvons faire un usage original de l'option « [-solarize](https://imagemagick.org/command-line-options/#solarize) » (voir l'exemple IM sur la solarisation). Appliquer cette opération à n'importe quelle image fait que toute couleur claire devient une couleur sombre (étant inversée). À ce titre, toute couleur presque blanche deviendra une couleur presque noire. À partir d'une telle image, une simple analyse statistique de l'image déterminera si l'image est purement (ou presque purement) en noir et blanc.

   magick wmark_dragon.jpg  -solarize 50% -colorspace Gray  wmark_bw_test.png
   magick identify -verbose -alpha off wmark_bw_test.png | \
       sed -n '/Histogram/q; /Colormap/q; /statistics:/,$ p'  > wmark_stats.txt

[IM Output] [IM Output] | | [IM Text]

Si vous regardez les statistiques ci-dessus, vous verrez que la « moyenne » (mean) de la couleur est très proche du noir pur (« 0 »), tandis que l'« écart-type » (standard deviation) est lui aussi très petit, mais plus grand que la « moyenne ». Ainsi, cette image doit être majoritairement en noir et blanc purs, avec très peu de couleurs ou de gris de tons moyens. Pour les images en niveaux de gris et en couleur en général, la « moyenne » sera bien plus grande, et l'« écart-type » généralement plus petit que la moyenne. Quand cela se produit, cela signifie que l'image solarisée contient très peu de noir presque pur. Autrement dit, très peu de couleurs noires ou blanches pures sont présentes. Répétons ce test avec l'image granite intégrée.

   magick granite: granite.jpg
   magick granite.jpg -solarize 50% -colorspace Gray  granite_bw_test.png
   magick identify -verbose -alpha off granite_bw_test.png | \
     sed -n '/Histogram/q; /Colormap/q; /statistics:/,$ p' > granite_stats.txt

[IM Output] [IM Output] | | [IM Text]

Remarquez comme la « moyenne » est maintenant bien plus grande, vers le milieu de la plage de couleurs, avec un « écart-type » bien plus petit que la taille de la « moyenne ». Depuis IM v6.4.8-3, vous verrez aussi deux autres valeurs statistiques qui peuvent aider à déterminer le type d'image. Le « Kurtosis » (aplatissement) et la « Skewness » (asymétrie) sont tous deux relativement grands (et positifs) dans la première image en noir et blanc, ce qui reflète aussi le fait que très peu de gris sont en jeu comparé à une image en niveaux de gris. Toutefois, « moyenne » vs « écart-type » reste probablement le meilleur indicateur à des fins de comparaison. Notez que cette comparaison ne distingue pas entre « noir sur blanc » et « blanc sur noir », mais une fois que vous savez qu'il ne s'agit pas vraiment d'une image en niveaux de gris, un simple contrôle de la moyenne normale de l'image vous indiquera quelle est réellement la couleur d'arrière-plan.

Images à touches de couleur

Ces images échouent au test de niveaux de gris ci-dessus, mais restent en noir et blanc avec toutefois une petite zone ou tache de couleur. De petites taches de couleur pourraient facilement être noyées dans la moyenne globale d'une grande image, et être incorrectement classées comme niveaux de gris. Nous ne nous intéressons pas aux images avec, disons, un seul pixel de couleur, qui est probablement une erreur de bit, ni à un mouchetage de tels pixels sur l'image. Mais plutôt à une image avec une flèche colorée ou un petit objet coloré. Autrement dit, une tache de couleur concentrée. Dans une discussion sur le forum IM False positive for greyscale images using the "saturation test", on a envisagé de découper les images en sections plus petites, puis de rechercher une saturation élevée dans l'une de ces zones. Cela a conduit à la méthode suivante.

  • convertir l'image dans un espace colorimétrique doté d'un canal de saturation ou de chroma
  • redimensionner l'image en plus petit dans un rapport de 1:50 (2 %) (par ex. une « taille de tache » pour la couleur)
  • appliquer un seuil pour obtenir la valeur de saturation/chroma maximale

Les taches individuelles ou très petites seront supprimées, mais une plus grande tache de couleur aura au moins un pixel coloré dans l'image redimensionnée.

Images en teinte de tons moyens

[IM Output] Les images en sépia, ou dont les gris de tons moyens sont teintés d'une couleur de rehaut (par exemple l'image de droite) peuvent se révéler bien plus difficiles à distinguer. Générer de telles images est facile, comme le montre le teintage de tons moyens, même si elles ne sont pas très courantes. Les couleurs forment toujours un dégradé (une droite) de couleurs dans l'espace colorimétrique, mais ce dégradé suit un chemin courbe, typiquement une sorte de parabole, dans un plan. Mais distinguer de telles images peut être très difficile. Une technique consiste à obtenir l'écart-type des teintes qui n'ont pas une saturation extrêmement faible. Toutes les teintes d'une image en teinte de tons moyens devraient être très similaires, même si elles ne sont pas nombreuses. Cette technique a été présentée dans un message précis de How to check image color or back and white. Rappelez-vous simplement que la teinte (Hue) est une valeur cyclique, et qu'elle se referme autour de la couleur « rouge ». Pour tester correctement, vous devrez peut-être le faire deux fois, avec les teintes décalées de 180 degrés. De plus, la teinte n'a pas de réelle signification pour une couleur à très faible saturation (gris), aussi une telle couleur devrait-elle être ignorée lors du test de l'écart-type des teintes.

Texte vs dessin au trait

Si vous avez une image presque entièrement d'une seule couleur (typiquement le blanc), vous pouvez essayer de voir si le contenu de l'image peut être classé soit comme du texte, soit comme un dessin au trait. Le texte comportera de nombreux petits objets déconnectés, généralement groupés en lignes horizontales. En revanche, les dessins au trait devraient avoir presque tout relié ensemble comme un tout, et faire intervenir de nombreux angles différents. Notez que les images en couleur de type dessin animé pourraient aussi être converties en dessin au trait pour une comparaison d'images plus simple ; disposer d'une méthode de comparaison de dessins au trait serait donc utile. Un volontaire ? Pour en savoir plus sur le texte, plusieurs techniques ont été discutées sur les forums IM, Check if image contains text.

Réel vs type dessin animé

Fondamentalement, les dessins animés ont des blocs de couleur très spécifiques avec des régions aux bordures nettes, souvent rendues plus nettes par l'emploi d'une ligne noire de séparation. Ils ont aussi généralement des effets de dégradé ou d'ombrage minimaux. Les images du monde réel ont en revanche beaucoup d'effets de bord doux, de dégradés de couleur et de textures, et emploient beaucoup de couleurs différentes. Ce n'est bien sûr pas toujours vrai. Une image du monde réel peut avoir une qualité très proche du dessin animé, surtout si un contraste très élevé est utilisé, et certains dessins animés modernes sont si réalistes qu'il peut être difficile de les classer comme dessins animés. En général, la principale différence entre une image du monde réel et un dessin animé réside dans les textures et les dégradés. À ce titre, pour déterminer de quel type d'image il s'agit, il faut comparer l'image à la même image dont la texture de fine échelle a été retirée. Une grande différence signifie que l'image est plus « réaliste » et proche du « monde réel », plutôt que « caricaturale » ou « plate ». Rappelez-vous aussi qu'un dessin au trait, un croquis d'artiste et du texte peuvent aussi être de style très proche du dessin animé, mais avoir une texture et un détail si fins que ce qui précède pourrait considérer l'image comme relevant du monde réel. À ce titre, les dessins au trait et les croquis devraient être séparés au préalable.
Jim Van Zandt propose cette solution…

  • écrire la couleur de chaque pixel
  • trier par couleur
  • écrire le décompte de pixels pour chaque couleur
  • trier par décompte de pixels
  • Parcourir la liste jusqu'à avoir rendu compte de la moitié des pixels de l'image.
  • Si #pixels >>> #couleurs, alors c'est de type dessin animé.

La section initiale peut être classée comme un histogramme. Voyez les exemples de « [histogram:](files.html#histogram) ».
Si vous avez élaboré une sorte de schéma de classification d'images… Même si ce n'est que grossièrement, faites-nous part de vos résultats, afin que d'autres (moi y compris) puissent en profiter.


Traitement de types d'images spécifiques

Voici des notes et informations sur des techniques de détermination d'images plus spécifiques.

Mauvaise numérisation ou impressions

Dans le monde réel, les choses ne fonctionnent jamais tout à fait aussi parfaitement qu'on le voudrait. Les scanners ont des capteurs défectueux et les tambours d'imprimante des rayures. Ces deux problèmes se traduisent généralement par des numérisations et des impressions contenant de longues lignes verticales. Déterminer si une image comporte ces lignes verticales est cependant assez facile. L'idée est de moyenner ensemble les pixels de toutes les rangées d'une image. Tout « défaut » apparaîtra comme un pic net dans la rangée de pixels finale, dont le nombre peut être compté à l'aide d'un « histogramme à seuil » de la rangée de pixels.

FUTUR -- exemple d'image nécessaire pour les tests
    magick bad_printout.png -crop 0x1+0+0 -evaluate-sequence mean \
            -threshold 50% -format %c histogram:info:-

méthode plus rapide mais qui nécessite la hauteur de l'image (supposée être 1024)
    magick bad_printout.png -scale 1024x1 \
            -threshold 50% -format %c histogram:info:-

Une fois que vous avez déterminé et retiré de telles « mauvaises lignes » d'un fax, d'une impression ou d'une numérisation, vous pouvez poursuivre vos autres tests sans avoir à vous soucier de ce type de défaut du monde réel.

Fax vierge

Vous devrez d'abord « [-shave](https://imagemagick.org/command-line-options/#shave) » (raboter) tout en-tête et pied de page qu'un fax aurait pu ajouter à une page. Vous pouvez ensuite soit faire un « histogramme à seuil » (voir précédemment) pour voir combien il y a de pixels noirs individuels.

FUTUR -- exemple d'image nécessaire pour les tests
    magick blank_fax.png -threshold 50% -format %c histogram:info:-

Ou vous pouvez effectuer un rognage bruité (Noisy Trim) pour voir si l'image contient réellement une zone unie ou des objets dignes de votre attention.

FUTUR -- exemple d'image nécessaire pour les tests

Images spammées

Une image spammée montrera généralement un pic de couleur pure prédominant dans l'histogramme de couleurs de l'image. Un contrôle de la couleur dans l'image montrera généralement qu'elle se situe dans l'un des coins de l'image. Cela ne fonctionnera toutefois pas avec les images de type dessin animé.

Images de spam par e-mail

Ce sont des images conçues pour passer à travers les divers filtres anti-spam. Fondamentalement, le texte de la publicité est caché dans une image à l'aide de diverses couleurs, avec de la « saleté » supplémentaire et d'autre bruit ajoutés pour le rendre plus difficile à détecter. Et bien que celles-ci soient difficiles à distinguer, disons, d'un logo d'en-tête d'e-mail d'entreprise, elles sont aussi généralement bien plus grandes que le logo d'e-mail typique. Une technique de détection consiste à appliquer un grand filtre médian à l'image. Le texte de spam par e-mail disparaîtra généralement, tandis qu'un logo ou une image restera très coloré.


Métriques d'image, trouver rapidement les images à comparer

Une métrique représente une sorte d'« empreinte » pour représenter une image, dans une très faible quantité de mémoire. Des images similaires devraient produire une métrique similaire. Notez toutefois qu'une métrique n'est pas conçue pour trouver réellement les images correspondantes, mais pour tenter d'écarter les images qui ne correspondent assurément pas. Autrement dit, une bonne métrique vous permettra d'écarter la plupart des images de comparaisons ultérieures, réduisant ainsi le temps nécessaire pour parcourir toutes les images.

Couleur moyenne d'une image

Vous pouvez utiliser -scale pour obtenir une couleur moyenne d'une image, mais
je vous suggère aussi de retirer les bordures extérieures de l'image afin de
réduire l'effet de toute « peluche » ayant pu être ajoutée autour de l'image.

    magick image.png  -gravity center -crop 70x70%+0+0 \
            -scale 1x1\! -depth 8 txt:-

Sinon, pour obtenir une couleur « centroïde pondéré », fondée sur le
regroupement de couleurs plutôt que sur une moyenne, vous pouvez utiliser -colors

    magick rose: -colors 1 -crop 1x1+0+0 -depth 8 -format '%[pixel:s]' info:-
    rgb(146,89,80)

Cela fera généralement correspondre les images qui ont été redimensionnées, légèrement rognées, pivotées ou translatées. Mais cela fera aussi correspondre beaucoup d'images qui ne sont pas étroitement liées. Le plus gros problème est que cette métrique écartera généralement les images qui ont été éclaircies, assombries, ou dont la teinte globale a été modifiée. De plus, si c'est une excellente métrique pour les images en couleur et du monde réel, elle est totalement inutile pour les images en niveaux de gris. Toutes ces images se retrouvent généralement regroupées ensemble sans aucun regroupement supplémentaire au sein du type. Cela montre à son tour pourquoi une classification initiale des types d'images peut être vitale pour un bon tri et une bonne mise en correspondance des images.

Couleur prédominante d'une image

La couleur prédominante d'une image est un peu différente : au lieu de la moyenne qui fusionne les couleurs d'arrière-plan avec l'avant-plan, vous voulez trouver la couleur d'avant-plan la plus courante, et peut-être un pourcentage indiquant quelle part de l'image se compose de cette couleur prédominante. À ce titre, vous ne pouvez pas simplement prendre un histogramme de l'image, car l'image peut utiliser beaucoup de nuances individuelles de couleur plutôt qu'une couleur précise. Cela peut se faire à l'aide de la fonction de quantification bas niveau -segment, puis en prenant un histogramme. Cela présente un avantage par rapport à l'usage direct de -colors, car cela ne tente pas de fusionner des grappes de couleurs éloignées (au sens des couleurs), bien que les résultats puissent être plus difficiles à interpréter.

 EXEMPLE À VENIR

Après quoi un histogramme vous donnera la quantité de chacune des couleurs prédominantes. Toutefois, la couleur prédominante d'un dessin animé ou d'un dessin au trait est généralement la couleur d'arrière-plan de l'image. Cela n'est donc vraiment utile que pour les images du monde réel. En revanche, vous pourrez peut-être l'utiliser pour découvrir si une image possède un véritable arrière-plan, en la comparant à la couleur de bordure moyenne de l'image. Notez que la couleur prédominante d'une image est plus susceptible d'être fortement influencée par la couleur d'arrière-plan de l'image, plutôt que par l'objet d'intérêt. C'est-à-dire, généralement au centre ou près du centre de l'image.

Couleurs de bordure

En rognant à plusieurs reprises chacun des quatre bords (2 à 3 pixels au plus) d'une image, et en calculant la couleur moyenne des bordures, vous pouvez déterminer si une image est encadrée, et à quelle profondeur. S'il y a un arrière-plan bien défini pour l'image. Ou s'il existe une sorte de séparation de couleur ciel/terre ou premier plan/lointain sur l'ensemble de l'image. En comparant les couleurs moyennes des côtés à la couleur moyenne centrale de l'image, vous pouvez découvrir si l'image est uniforme, sans thème ni sujet central, comme une photo d'un paysage vide.

Histogramme - Mise en correspondance générale des couleurs

Pour une métrique concernant les types de couleurs présentes dans une image, on utilise un histogramme d'une sorte ou d'une autre. Cela se fait en créant un tableau de « casiers de couleur » (color bins) et en incrémentant le décompte de chaque « casier » à mesure que les couleurs sont rencontrées. Or, je ne vous vois pas stocker un grand histogramme pour chaque image ! Vous ne stockerez donc que les couleurs les plus prédominantes de l'histogramme, ou vous utiliserez un nombre bien plus réduit de casiers (avec plus de pixels dans chaque casier). Un histogramme ordinaire de « casiers de couleur » ne fonctionne pas vraiment très bien. La raison en est que chaque couleur tombera toujours dans un seul casier. C'est-à-dire que chaque pixel est ajouté à chaque casier sur une base du tout ou rien, sans aucun égard pour la proximité de cette couleur avec le bord d'un casier. Cela ne fait pas, à son tour, une bonne métrique. Une solution consiste à créer un histogramme dont les casiers se chevauchent. C'est-à-dire que chaque couleur (sauf peut-être le noir ou le blanc) tombera dans deux casiers de couleur. Ainsi, plus tard, lorsque vous comparerez les images, une couleur proche correspondra à au moins l'un de ces casiers. Une autre alternative consiste à créer l'histogramme en faisant contribuer chaque couleur à chaque « casier » selon sa proximité avec le centre du casier. Ainsi, une couleur au bord d'un casier se répartira en réalité entre deux casiers. Cela génère une sorte d'histogramme flou, ou interpolé, mais qui représenterait plus fidèlement une image, surtout lorsqu'un très petit nombre de « casiers » de couleur seulement est utilisé. De plus, les histogrammes portent traditionnellement soit uniquement sur la composante niveaux de gris d'une image, soit sur les trois composantes RVB séparées. Mais ce n'est pas une très bonne représentation. Vous pourriez plutôt essayer des histogrammes de teinte, de saturation et de luminance pour mieux représenter l'image. Sinon, pourquoi vous limiter à un histogramme unidimensionnel ? Pourquoi ne pas mapper les couleurs sur un ensemble de couleurs réelles réparties dans tout l'espace colorimétrique ! C'est-à-dire, plutôt que de casier uniquement la valeur « rouge », pourquoi ne pas la compter dans un casier de couleur tridimensionnel (dans quel que soit l'espace colorimétrique qui fonctionne le mieux). Cela génèrerait un histogramme qui représenterait fidèlement les couleurs présentes dans une image. Une telle métrique d'histogramme 3D pourrait être un simple tableau de, disons, 8x8x8 soit 2048 casiers. C'est-à-dire une métrique de 2 kilo-octets. Une recherche de couleur localiserait alors le bon nombre de casiers voisins, et obtiendrait un décompte interpolé des casiers proches. Ce qui représenterait le nombre de couleurs « proches » de cette couleur dans l'image !

Séparation des couleurs d'avant-plan/arrière-plan

En utilisant -colors, vous pouvez tenter de séparer l'image en parties d'avant-plan et d'arrière-plan, en réduisant l'image à seulement deux couleurs. Utiliser d'abord un filtre -median supprimera l'effet des détails mineurs, des bords de lignes et du bruit qui peuvent être présents dans l'image. Bien sûr, ce n'est pas très bon pour les images de type croquis, majoritairement blanches.

  magick rose: -median 5 +dither -colors 2 \
          -depth 8 -format %c histogram:info:-

Cela montre une couleur rouge et une couleur grise comme couleurs prédominantes de l'image. Un rognage/découpage vers le centre de l'image devrait alors déterminer ce qui est avant-plan et ce qui est arrière-plan.

  magick rose: -median 5 +dither -colors 2 \
          -trim +repage  -gravity center -crop 50% \
          -depth 8 -format %c histogram:info:-

Ce qui montre que la couleur rouge de la « rose » est la couleur d'avant-plan prédominante. Notez qu'une image de paysage peut se séparer différemment, en ce sens que vous obtenez une couleur de sol en bas et une couleur de ciel en haut. À ce titre, un examen sommaire de la façon dont les couleurs ont été séparées peut être très utile pour la détermination du type d'image. De plus, une image comportant du « spam » textuel montrera souvent une tache de couleur dans un coin, bien plus proéminente que le reste de l'image. Si vous la trouvez, recommencez avec 3 couleurs, puis effacez cette zone avec la couleur d'« arrière-plan » la plus courante trouvée avant d'effectuer votre test final. Cette technique est probablement un bon moyen de séparer les images en classes telles que « teint de peau », « verdure », « paysage », etc.

Matrice de couleurs moyennes

Un schéma de couleurs par matrice trois sur trois (« -scale 3x3\! ») est un schéma de classification de couleurs raisonnable. Il séparera et regroupera très bien les images similaires. Par exemple, les croquis (tous presque blancs), les niveaux de gris, les paysages, les paysages marins, les pièces, les visages, etc., seront tous séparés en groupes de base et similaires (en théorie). C'est aussi une métrique raisonnable pour indexer les images en vue de générer des mosaïques de photos. La sortie du format d'image NetPBM est particulièrement adaptée à la génération d'une telle métrique, car il peut produire uniquement les valeurs des pixels sous forme de nombres textuels. Rappelez-vous que cela produirait un résultat à 27 dimensions (3x3 couleurs de 3 valeurs), aussi un algorithme de regroupement multidimensionnel pourrait-il être nécessaire. Connaissez-vous un bon programme/algorithme de regroupement 3D ? Par exemple, voici les couleurs RVB 3 x 3 (en profondeur 8) pour le logo IM.

  magick logo: -scale 3x3\! -compress none -depth 8 ppm:- |\
    sed '/^#/d' | tail -n +4

  251 241 240 245 234 231 229 233 236 254 254 254
  192 196 204 231 231 231 255 255 255 211 221 231
  188 196 210

Ce qui précède peut être amélioré en utilisant des valeurs de 16 bits, et éventuellement en rognant 10 % des bordures pour retirer le logo et les débris de cadre ayant pu être ajoutés…

  magick logo: -gravity center -crop 80% -scale 3x3\! \
          -compress none -depth 16 ppm:- |   sed '/^#/d' | tail -n +4

  63999 59442 58776 62326 58785 58178 51740 54203 54965 65277 65262 65166
  45674 47023 49782 56375 55648 55601 65535 65535 65535 52406 55842 58941
  44635 48423 52881

Bien sûr, comme la métrique de couleur moyenne précédente, celle-ci aura aussi du mal à apparier les images dont la couleur a été modifiée, par exemple par des changements de teinte ou de luminosité. (Voir la section suivante) De plus, cette métrique peut séparer les dessins au trait au sein de son regroupement, mais seulement de façon très générale. De tels dessins seront tout de même regroupés davantage par la couleur du « papier » de fond que par le contenu, et nécessitent généralement un « seuil » de similitude plus petit que les images en couleur.

Matrice de différence de couleurs

Le plus gros problème lié à l'utilisation des couleurs directement comme métrique est que vous liez l'image à une couleur générale particulière. Cela signifie que toute image ayant été éclaircie ou assombrie, ou dont la teinte a été modifiée, ne sera pas regroupée avec les autres. Une solution consiste à soustraire d'une manière ou d'une autre la couleur prédominante ou moyenne de l'image de la métrique, et l'usage d'une matrice de couleurs rend cela possible. Ici, par exemple, je soustrais la couleur moyenne du milieu, ou du centre, de toutes les couleurs environnantes de la matrice.

  magick logo: -gravity center -crop 80% -scale 3x3\! -fx '.5+u-p{1,1}' \
          -compress none -depth 16 ppm:- | sed '/^#/d' | tail -n +4

  51093 45187 41761 49419 44529 41163 38834 39947 37950 52371 51007 48152
  32767 32767 32767 43469 41393 38587 52629 51279 48521 39500 41587 41926
  31729 34168 35867

Notez que j'ajoute .5 à la différence, car on ne peut pas enregistrer une valeur de couleur négative dans une image. De plus, l'usage de l'opérateur lent « [-fx](https://imagemagick.org/command-line-options/#fx) » est acceptable, car seuls 9 pixels sont traités. Notez que le pixel central (« 32767 32767 32767 » au début de la deuxième ligne ci-dessus) ne changera pas beaucoup (tout changement n'est dû qu'à de légères erreurs d'arrondi), et pourrait être retiré du résultat, réduisant la métrique à 24 dimensions (valeurs). Sinon, vous pouvez soustraire la couleur moyenne de l'image des 9 valeurs de couleur.

  magick logo: -scale 3x3\! \( +clone -scale 1x1 \) -fx '.5+u-v.p{0,0}' \
          -compress none ppm:- | sed '/^#/d' | tail -n +4

  38604 35917 34642 37011 33949 32441 32839 33841 33649 39447 39259 38369
  23358 24377 25436 33538 33174 32426 39612 39434 38605 28225 30576 32319
  22271 24381 27021

Cela pourrait aussi se faire par le comparateur de métrique, plutôt que par le générateur de métrique. La métrique sépare et regroupe toujours très bien les images en couleur, plaçant les images similaires très près les unes des autres, indépendamment de tout changement général de couleur ou de luminosité. Elle reste toutefois sensible aux changements de contraste. Cette modification de métrique pourrait en fait être effectuée pendant le processus de comparaison, de sorte qu'une métrique de matrice de couleurs brute puisse tout de même être utilisée comme métrique d'image standard à collecter, mettre en cache et comparer. C'est ce que je fais moi-même désormais pour les comparaisons d'images à grande échelle. Contrairement à une simple moyenne de couleurs, vous pouvez utiliser cette métrique pour différencier des images de dessin au trait distinctes. Toutefois, comme les dessins au trait utilisent une échelle de couleurs linéaire (toutes les couleurs tombent sur une droite dans l'espace de métriques), les différences entre images sont environ 1/3 de celles des images en couleur. À ce titre, un seuil très différent est nécessaire lors de la comparaison des dessins au trait. Il reste donc préférable de séparer les dessins au trait et les images en niveaux de gris des images en couleur. Autrement dit, c'est l'une des meilleures métriques que j'aie trouvées jusqu'à présent pour les images en couleur. Assurez-vous simplement de déterminer d'abord quelles images sont des dessins au trait, et de les comparer séparément à l'aide d'un seuil bien plus bas. Heureusement pour nous, la métrique elle-même peut servir à effectuer la séparation des images en niveaux de gris ou en image en couleur linéaire. Les suggestions sont bienvenues.

Différence des voisins

Ce qui précède génère une matrice 3x3, dont le pixel central est soustrait, et dont toutes les valeurs sont décalées vers un gris parfait. Une meilleure méthode consiste toutefois, au lieu de tenter d'enregistrer la couleur des cellules individuelles, à générer plutôt les différences entre chaque cellule et ses voisines (8 voisines). C'est-à-dire, au lieu d'enregistrer la couleur du coin supérieur gauche, enregistrer la différence entre ce coin et le haut-milieu, le centre et le milieu-gauche. Bien sûr, même avec un petit tableau 3x3, vous vous retrouverez avec une signature contenant 12 différences, même s'il n'est pas nécessaire d'encoder la différence complète, juste un niveau de différence général : par exemple égal, ou valeurs de différence positives/négatives grandes/petites. Cela est bien plus susceptible de trouver des images qui correspondent même entre des images contenant des couleurs radicalement différentes, car la couleur réelle ne joue aucun rôle dans la signature. La bibliothèque de comparaison d'images « libpuzzle » fait exactement cela, bien qu'elle utilise une matrice 9x9, seuls les pixels centraux de chaque cellule étant moyennés ensemble. Elle se limite aussi aux versions en niveaux de gris de l'image. La technique est entièrement définie dans un article au format postscript, Image Signature for Any Kind of Image. L'article aborde aussi les méthodes de stockage de cette signature dans une base de données, et la façon d'effectuer réellement une recherche pour trouver des images à la signature similaire (pas nécessairement identique). C'est le premier article que j'aie découvert à entrer réellement dans le détail de la manière de le faire. :-)

Hachage perceptuel

Réduisez l'image à un 8x8 et calculez une intensité moyenne. Chaque bit du hachage de 64 bits vaut alors 1 si le pixel est au-dessus de la moyenne, ou 0 s'il est en dessous. Pour comparer la similitude entre deux images, il vous suffit de comparer les hachages bit à bit, et de renvoyer une distance de Hamming. Plus la distance de Hamming est faible, plus les images sont similaires. Tout ce qui dépasse 21 / 64 est considéré comme non similaire. pHash semble utiliser un encodage YCbCr. Certains évoquent le travail direct sur la DCT du JPEG, et le plus prometteur travaille avec l'amplitude / la phase et la mappe sur un système de coordonnées log-polaires.


Mieux apparier les images

Notes et techniques diverses que je n'ai pas essayées, ou qui n'ont pas très bien fonctionné, pour comparer de plus grandes images en vue d'une mise en correspondance plus exacte.

Couleur de segmentation

Comme vous pouvez le voir, beaucoup des métriques ci-dessus utilisent un filtre de flou/médian suivi de techniques de réduction de couleurs ; ce sont des tentatives élémentaires de simplifier les images pour mieux permettre leur classification. Mais l'opérateur de quantification de couleurs n'est pas vraiment conçu à cet effet. Son rôle est de réduire les couleurs afin de mettre en évidence les détails importants de l'image. Pour la comparaison d'images, en revanche, nous ne voulons pas vraiment mettre en évidence ces caractéristiques, mais mettre en évidence les zones d'intérêt comparatif. C'est le rôle d'une technique de couleur apparentée, connue sous le nom de segmentation… À NOTER : d'après Leptonica : la segmentation d'image est la division de l'image en régions ayant des propriétés différentes. Cet opérateur bloque les zones de couleurs similaires en retirant le détail de ces zones. Ainsi, lorsque vous comparez les deux images, vous comparez des zones plutôt que des détails bas niveau des images. IM implémente un algorithme de segmentation, « [-segment](https://imagemagick.org/command-line-options/#segment) » ; pour ses détails d'implémentation, voyez SegmentImage(). Exemple :

  magick logo: -median 10 -segment 1x1 \
          +dither -scale 100x100\! segment_image.gif

Un problème est que -segment est TRÈS lent, et il ne semble fonctionner que pour de plus grandes images. Les petites images (comme un rose: ou un logo: mis à l'échelle 100x100) semblent aboutir à la production d'une seule couleur. Cela pourrait être un bug. Bien sûr, vous pouvez tout de même mettre l'image à l'échelle après l'avoir segmentée, comme nous l'avons fait ci-dessus. Ainsi, vous pouvez stocker un plus grand nombre d'images en mémoire pour les comparer entre elles. De plus, la segmentation résultante ne semble pas très bien fonctionner comparée à l'algorithme de segmentation d'image que fournit Leptonica. Voyez Leptonica: Color Segmentation. Une alternative à la segmentation d'IM consiste toutefois à détourner la fonction de quantification de couleurs pour trouver des zones de couleur similaire. Exemple :

  magick logo: -scale 100x100\! -median 3 \
          -quantize YIQ +dither -colors 3 segment_image.gif

L'inconvénient est que -color limite le nombre de zones de couleur pouvant être présentes dans une image, alors que segment tente de préserver les zones similaires, indépendamment du nombre de zones réellement présentes dans l'image (ou du moins c'est ce qu'il devrait faire).

Comparaison de contours sans couleur

La couleur d'une image est notoirement peu fiable, en particulier pour les images de type dessin animé. Différents utilisateurs pourraient tout à fait recolorer de telles images, ajouter des arrière-plans de couleurs différentes, ou même prendre un croquis et le colorier. Une façon d'apparier de telles images consiste à effectuer une réduction de couleurs élémentaire, comme dans la méthode ci-dessus, mais ensuite, plutôt que de comparer les images d'après la couleur résultante, à effectuer une détection de contours, et un traitement supplémentaire de sorte que seuls les contours des changements de couleur les plus importants soient utilisés pour les métriques et la comparaison des images. Par exemple…

  magick logo: -scale 100x100\! -median 3 \
          -quantize YIQ +dither -colors 3 -edge 1 \
          -colorspace gray -blur 0x1   outline_image.gif

Une alternative peut être d'utiliser -lat (seuil de zone locale, Local Area Threshold) pour la détection de contours, qui peut vous donner un meilleur contrôle…

  magick logo: -scale 100x100\! -median 3 \
          -quantize YIQ +dither -colors 3 \
          -lat 3x3-5% -negate \
          -colorspace gray -blur 0x1  outline_image.gif

Bien sûr, pour la comparaison, vous utiliseriez une méthode de comparaison de dessin au trait.
??? comment compareriez-vous des dessins au trait de façon exploitable ???
Multipliez les images ensemble et voyez si l'image résultante a augmenté ou réduit l'intensité des lignes. Les lignes non concordantes deviendront noires.


Caméras web

Ce qui a changé dans des caméras fixes

En cours de construction

Walter Perry rapporte… Le projet sur lequel je travaille consiste à traiter des groupes de 20 images envoyées par une caméra de surveillance en réponse à la détection d'un mouvement par la caméra. Ces caméras se trouvent dans des lieux distants et, une fois qu'elles détectent un mouvement, les images sont envoyées à un serveur local. Une fois sur le serveur local, je veux pouvoir « filtrer » les images qui ne contiennent pas ce qui a provoqué l'événement. J'utilise PerlMagick pour comparer la première image de la série (qui ne contiendra toujours rien d'autre que l'arrière-plan normal) avec le reste des images. J'obtiens une différence « moyenne » pour toutes les images, puis, si la différence individuelle est supérieure à la différence moyenne, je conserve l'image, car elle contient quelque chose. Cette approche fonctionne à merveille, de jour comme de nuit, quelles que soient les conditions d'éclairage. J'essayais au départ de n'utiliser qu'un pourcentage de différence au-dessus de la première image, mais ce n'était pas très fiable et dépendait vraiment des conditions d'éclairage. Sur la base de cette comparaison, je détermine ensuite quelles images ont un « contenu » et quelles images sont vides de tout mouvement. Une fois que j'obtiens uniquement les images contenant du « mouvement ».