Как найти одно изображение внутри другого? - PullRequest
29 голосов
/ 18 марта 2010

У меня есть 2 изображения BMP. ImageA - скриншот (пример) ImageB является подмножеством этого. Скажем, например, значок.

Я хочу найти координаты X, Y ImageB в ImageA (если он существует).

Есть идеи, как мне это сделать?

Ответы [ 4 ]

16 голосов
/ 25 февраля 2012

Вот быстрый пример, но он медленный, занимает около 4-6 секунд, но он делает именно то, что вы ищете, и я знаю, что этот пост старый, но если кто-то еще недавно посещал этот пост Вы можете посмотреть эту вещь вам нужно .NET AForge пространство имен или фреймворк Google и установите его включить пространство имен AForge в свой проект и все он находит фотографию с другим и выдает координаты.

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 голосов
/ 18 марта 2010
  1. Так есть ли искажение ImageB в ImageA?
  2. Насколько "точными" являются изображения, например, пиксель за пикселем, они будут одинаковыми ?
  3. Сколько вычислительных мощностей у вас есть для этого?

Если ответы на первые два вопроса Нет и Да , то у вас есть простая проблема. Это также помогает узнать ответ на Q3 .

Обновление:

Основная идея такова: вместо сопоставления окна вокруг каждого пикселя в изображении B с каждым пикселем в изображении A и проверки корреляции, давайте определим точки интереса (или особенности) в обоих изображениях, которые будут отслеживаемыми, Таким образом, похоже, что углы действительно отслеживаются, так как область вокруг них похожа (не вдаваясь в детали) - следовательно, давайте найдем несколько действительно сильных углов на обоих изображениях и найдем углы, которые выглядят наиболее похожими.

Это сводит проблему поиска каждого пикселя в B с A к поиску, скажем, 500 углов в B с 1000 углами в A (или что-то в этом роде) - намного быстрее.

И что удивительно, у вас есть несколько таких угловых детекторов в вашем распоряжении в OpenCV . Если вы не чувствуете, что используете emguCV (C # varriant), то используйте детектор FAST , чтобы найти совпадающие углы и, таким образом, найти несколько объектов между изображениями. После этого вы можете найти местоположение в верхнем левом углу изображения.

1 голос
/ 19 марта 2010

Если изображение B является точным подмножеством изображения A (то есть значения пикселей точно такие же), это не проблема обработки изображения, это просто сопоставление строк в 2D. В 99% случаев взятие линии из середины B и сопоставление ее с каждой линией A будет делать то, что вы хотите, и супер быстро & mdhas; Я думаю, в C # есть функция для этого. После того, как вы получите свои совпадения (как правило, несколько из них), просто сравните весь B с соответствующей частью A.

Единственная проблема, которую я вижу в этом, заключается в том, что в некоторых случаях вы можете получить слишком много совпадений. Например. если A - ваш рабочий стол, B - значок, и вам не повезло выбрать линию в B, состоящую только из фона. Эту проблему легко решить (вам нужно выбирать строки из B немного более тщательно), но это зависит от специфики вашей проблемы.

...