web-dev-qa-db-fra.com

Comment trouver une image à l'intérieur d'une autre?

J'ai 2 images bmp. ImageA est une capture d'écran (exemple) ImageB est un sous-ensemble de celui-ci. Dites par exemple une icône.

Je souhaite trouver les coordonnées X, Y de ImageB dans ImageA (s’il existe).

Une idée de comment je ferais ça?

27
esac
  1. Y a-t-il une déformation de ImageB dans ImageA? 
  2. À quel point les images sont-elles "exactes", pixel par pixel, elles seront identiques à mêmes?
  3. Combien de puissance de calcul avez-vous pour cela?

Si les réponses aux deux premières questions sont Non et Oui, alors vous avez un problème simple. Il est également utile de connaître la réponse à Q3.

Mise à jour:

L'idée de base est la suivante: au lieu de faire correspondre une fenêtre autour de chaque pixel de l'imageB avec chaque pixel de l'imageA et de vérifier la corrélation, identifions les points d'intérêt (ou caractéristiques) des deux images qui seront suivis. Donc, il semble que les coins soient vraiment repérables puisque la zone autour est assez similaire (sans entrer dans les détails) - par conséquent, trouvons des coins vraiment forts dans les deux images et recherchons les coins qui se ressemblent le plus. 

Cela réduit le problème de la recherche de chaque pixel dans B avec A à la recherche, par exemple, de 500 coins en B avec un 1000 coins en A (ou quelque chose comme ça) - beaucoup plus rapidement.

Et ce qui est génial, c’est que vous avez plusieurs détecteurs de coin de ce type à votre disposition dans OpenCV . Si vous ne sentez pas que vous utilisez emguCV (C # varriant), utilisez le détecteur FAST pour trouver les angles correspondants et localiser ainsi plusieurs entités entre vos images. Une fois que vous avez cela, vous pouvez trouver l'emplacement du coin supérieur gauche de l'image.

15
Jacob

Voici un échantillon rapide, mais cela prend lentement environ 4 à 6 secondes, mais il fait exactement ce que vous recherchez et je sais que ce message est ancien, mais si quelqu'un d'autre le visite récemment, vous pourrez le regardervous Il faut un espace de noms .NET AForge ou un framework pour le google et l’installer inclure l’espace de noms AForge dans votre projet. 

System.Drawing.Bitmap sourceImage = (Bitmap)Bitmap.FromFile(@"C:\SavedBMPs\1.jpg");
            System.Drawing.Bitmap template = (Bitmap)Bitmap.FromFile(@"C:\SavedBMPs\2.jpg");
            // create template matching algorithm's instance
            // (set similarity threshold to 92.1%)

           ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching(0.921f);
                // find all matchings with specified above similarity

                TemplateMatch[] matchings = tm.ProcessImage(sourceImage, template);
                // highlight found matchings

           BitmapData data = sourceImage.LockBits(
                new Rectangle(0, 0, sourceImage.Width, sourceImage.Height),
                ImageLockMode.ReadWrite, sourceImage.PixelFormat);
            foreach (TemplateMatch m in matchings)
            {

                    Drawing.Rectangle(data, m.Rectangle, Color.White);

                MessageBox.Show(m.Rectangle.Location.ToString());
                // do something else with matching
            }
            sourceImage.UnlockBits(data);
15
Mandah Mr.

Si l'image B est un sous-ensemble exact de l'image A (c'est-à-dire que les valeurs des pixels sont exactement les mêmes), il ne s'agit pas d'un problème de traitement d'image, il s'agit simplement d'une correspondance de chaîne en 2D. Dans 99% des cas, prendre une ligne du milieu de B et le faire correspondre à chaque ligne de A fera ce que vous voulez, et très vite & mdhas; Je suppose que C # a une fonction pour cela. Une fois que vous avez obtenu vos matchs (normalement quelques-uns), il vous suffit de comparer l'ensemble de B à la partie appropriée de A. 

Le seul problème que je peux voir avec ceci est que dans certains cas, vous pouvez obtenir trop de correspondances. Par exemple. si A est votre bureau, B est une icône et vous n'avez pas la chance de choisir une ligne dans B composée uniquement d'arrière-plan. Ce problème est facile à résoudre (vous devez choisir un peu plus soigneusement les lignes de B), mais cela dépend des spécificités de votre problème.

1
AVB
0
SwDevMan81