Подтвердить что ты не робот

Как найти одно изображение внутри другого?

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

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

Любая идея, как я это сделаю?

4b9b3361

Ответ 1

  • Итак, есть ли деформация ImageB в ImageA?
  • Как "точные" изображения, как в пикселях для пикселя, они будут одинаковыми?
  • Сколько вычислительной мощности у вас есть для этого?

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

Update:

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

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

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

Ответ 2

Здесь быстрый пример, но он медленный занимает около 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 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);

Ответ 4

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

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