Как найти Waldo с Mathematica?

Это подшучивало над выходными: что это хороший способ решить эти Где Waldo? ['Wally' за пределами Северной Америки] головоломки, используя Mathematica (обработка изображений и другие функции)?

Вот что у меня есть до сих пор, функция, которая немного уменьшает визуальную сложность путем затемнения некоторые из некрасных цветов:

whereIsWaldo[url_] := Module[{waldo, waldo2, waldoMask},
    waldo = Import[url];
    waldo2 = Image[ImageData[
        waldo] /. {{r_, g_, b_} /;
          Not[r > .7 && g < .3 && b < .3] :> {0, 0,
          0}, {r_, g_, b_} /; (r > .7 && g < .3 && b < .3) :> {1, 1,
          1}}];
    waldoMask = Closing[waldo2, 4];
    ImageCompose[waldo, {waldoMask, .5}]
]

И пример URL-адреса, где это "работает":

whereIsWaldo["http://www.findwaldo.com/fankit/graphics/IntlManOfLiterature/Scenes/DepartmentStore.jpg"]

(Waldo находится в кассе):

Mathematica graphic

Ответ 1

Я нашел Уолдо!

waldo had been found

Как я это сделал

Во-первых, я отфильтровываю все цвета, которые не красные

waldo = Import["http://www.findwaldo.com/fankit/graphics/IntlManOfLiterature/Scenes/DepartmentStore.jpg"];
red = Fold[ImageSubtract, #[[1]], Rest[#]] &@ColorSeparate[waldo];

Затем я вычисляю соотношение этого изображения с простым черно-белым рисунком, чтобы найти красные и белые переходы в рубашке.

corr = ImageCorrelate[red, 
   [email protected][ConstantArray[1, {2, 4}], ConstantArray[0, {2, 4}]], 
   NormalizedSquaredEuclideanDistance];

Я использую Binarize, чтобы выделить пиксели в изображении с достаточно высокой корреляцией и нарисовать вокруг них белый круг, чтобы подчеркнуть их, используя Dilation

pos = Dilation[ColorNegate[Binarize[corr, .12]], DiskMatrix[30]];

Мне пришлось немного поиграть с уровнем. Если уровень слишком высок, выбрано слишком много ложных срабатываний.

Наконец, я комбинирую этот результат с исходным изображением, чтобы получить результат выше

found = ImageMultiply[waldo, ImageAdd[ColorConvert[pos, "GrayLevel"], .5]]

Ответ 2

Мое предположение о "пуленепробиваемом способе сделать это" (думаю, что ЦРУ найдет Вальдо в любом спутниковом изображении в любое время, а не только одно изображение без конкурирующих элементов, например полосатые рубашки)... Я бы тренировал машина Больцмана на многих изображениях Вальдо - все варианты его сидения, стоя, окклюзии и т.д.; рубашку, шляпу, камеру и все работы. Вам не нужен большой корпус Waldos (может быть, 3-5 будет достаточно), но чем больше, тем лучше.

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

Вот как работают OCR, считыватели почтовых индексов и беспорядочное распознавание рукописного ввода. В основном вы знаете, что ответ есть, вы знаете более или менее то, на что оно должно выглядеть, и все остальное может иметь общие элементы, но определенно "не оно", поэтому вы не беспокоитесь о "не он", вы просто посмотрите на вероятность "этого" среди всех возможных "это вы видели раньше" (например, в почтовых индексах вы тренировали BM всего за 1 с, всего за 2 с, всего за 3 с и т.д., затем кормили каждый на каждую машину, и выберите тот, который имеет наибольшую уверенность). Это работает намного лучше, чем одна функция обучения нейронной сети для всех чисел.

Ответ 3

Я согласен с @GregoryKlopper в том, что правильным способом решения общей проблемы поиска Waldo (или любого объекта интереса) в произвольном изображении было бы обучение надзорному классификатору машинного обучения. Используя множество положительных и отрицательных помеченных примеров, такой алгоритм, как Поддержка векторной машины, Boosted Decision Stump или Boltzmann Machine, вероятно, будет подготовлена ​​для достижения высокой точности по этой проблеме. Mathematica даже включает эти алгоритмы в Механизм машинного обучения.

Две проблемы с обучением классификатора Waldo:

  • Определение правильного преобразования функции изображения. Здесь будет полезен ответ @Heike: красный фильтр и деформированный шаблонный детектор (например, вейвлет или декомпозиция DCT) будут хорошим способом превратить необработанные пиксели в формат, который может изучить алгоритм классификации. Также потребуется блочная декомпозиция, которая оценивает все подразделы изображения... но это упрощается благодаря тому, что Waldo является a) всегда примерно одного размера и b) всегда присутствует ровно один раз в каждом изображении.
  • Получение достаточных примеров обучения. SVM работают лучше всего по меньшей мере с 100 примерами каждого класса. Коммерческие приложения повышения (например, фокусировка лица в цифровых камерах) обучаются миллионам положительных и отрицательных примеров.

Быстрый поиск изображений Google показывает некоторые хорошие данные - я собираюсь собирать некоторые примеры обучения и кодировать это прямо сейчас!

Однако даже подход машинного обучения (или основанный на правилах подход, предложенный @iND) будет бороться за изображение, подобное Land of Waldos!

Ответ 4

Я не знаю Mathematica., очень жаль. Но мне нравится ответ выше, по большей части.

Тем не менее существует серьезный недостаток в том, чтобы полагаться только на полосы, чтобы получить ответ (у меня лично нет проблем с одной ручной настройкой). Здесь представлен пример (представленный Brett Champion, здесь), который показывает, что они время от времени разбивают шаблон рубашки. Таким образом, он становится более сложным.

Я попробовал бы подход формы id и цветов, наряду с пространственными отношениями. Как распознавание лиц, вы можете искать геометрические узоры при определенных соотношениях друг от друга. Оговорка состоит в том, что обычно одна или несколько из этих форм закрыты.

Получите баланс белого на изображении и красным красным цветом на изображении. Я считаю, что Waldo всегда имеет одно и то же значение/оттенок, но изображение может быть от сканирования или плохой копии. Затем всегда обращайтесь к массиву цветов, которые на самом деле есть Уолдо: красный, белый, темно-коричневый, синий, персиковый, {цвет обуви}.

Существует рубашка, а также брюки, очки, волосы, лицо, обувь и шляпа, которые определяют Вальдо. Кроме того, по отношению к другим людям на изображении, Уолдо находится на узкой стороне.

Итак, найдите случайных людей, чтобы получить высоту людей на этом рисунке. Измерьте среднюю высоту кучки вещей в случайных точках на изображении (простой контур произведет немало отдельных людей). Если каждая вещь не находится в пределах какого-то стандартного отклонения друг от друга, на данный момент они игнорируются. Сравните среднее значение высоты с высотой изображения. Если соотношение слишком велико (например, 1: 2, 1: 4 или аналогично близко), повторите попытку. Запустите его 10 (?) Раз, чтобы убедиться, что образцы все довольно близко друг к другу, исключая любое среднее значение, которое находится за пределами стандартного отклонения. Возможно в Mathematica?

Это ваш размер Вальдо. Уолсо тощий, поэтому вы ищете что-то 5: 1 или 6: 1 (или что-то еще) ht: wd. Однако этого недостаточно. Если Уолдо частично скрыт, высота может измениться. Итак, вы ищете блок с красно-белым, который ~ 2: 1. Но должно быть больше индикаторов.

  • У Вальдо есть очки. Найдите два круга 0,5: 1 над красно-белым.
  • Синие брюки. Любое количество синего цвета с одинаковой шириной на любом расстоянии между красно-белым и расстоянием до его ног. Обратите внимание, что он носит короткую рубашку, поэтому ноги не слишком близки.
  • Шляпа. Красно-белое любое расстояние до двух раз выше его головы. Обратите внимание, что у него должны быть темные волосы внизу, и, возможно, очки.
  • Длинные рукава. красно-белый под некоторым углом от основного красно-белого.
  • Темные волосы.
  • Цвет обуви. Я не знаю цвета.

Любой из них может применяться. Это также отрицательные проверки против похожих людей на рис. Например, # 2 отрицает ношение красно-белого фартука (слишком близко к обуви), № 5 устраняет светлые волосы. Кроме того, форма является только одним показателем для каждого из этих тестов., цвет один на указанном расстоянии может дать хорошие результаты.

Это сократит области обработки.

Сохранение этих результатов приведет к созданию набора областей, в которых должен быть Waldo. Исключить все остальные области (например, для каждой области, выберите круг, вдвое превышающий средний размер человека), а затем запустите процесс, который @Heike выложил с удалением всего, кроме красного, и так далее.

Любые мысли о том, как это кодировать?


Edit:

Мысли о том, как это кодировать., исключить все области, кроме красного Уолдо, скелеризовать красные области и обрезать их до одной точки. Сделайте то же самое для волос Waldo коричневого цвета, брюки Waldo blue, цвета обуви Waldo. Для цвета кожи Уолдо исключить, затем найти схему.

Далее, исключить не красные, расширить (много) все красные области, затем скелетонизировать и обрезать. Эта часть даст список возможных точек центра Вальдо. Это будет маркер для сравнения всех остальных цветовых разделов Waldo.

Отсюда, используя скелетонированные красные области (а не расширенные), подсчитывайте линии в каждой области. Если есть правильное число (четыре, правильно?), Это, безусловно, возможная область. Если нет, я просто исключаю его (как центр Вальдо... он все равно может быть его шляпой).

Затем проверьте, есть ли фигура лица выше, указатель на волосы выше, нижнее белье, нижнее белье и т.д.

Пока еще нет кода - все еще чтение документов.

Ответ 5

У меня есть быстрое решение для поиска Waldo с использованием OpenCV.

Я использовал функцию , соответствующую шаблону, доступную в OpenCV, чтобы найти Waldo.

Для этого необходим шаблон (duh...). Поэтому я обрезал Waldo с исходного изображения и использовал его в качестве шаблона.

введите описание изображения здесь

Затем я назвал функцию cv2.matchTemplate() вместе с нормированным коэффициентом корреляции в качестве используемого метода. Он вернул высокую вероятность в одном регионе, как показано ниже в белом (где-то в левом верхнем углу):

введите описание изображения здесь

Положение наивысшей вероятной области было найдено с помощью функции cv2.minMaxLoc(), которую я тогда использовал, чтобы нарисовать прямоугольник, чтобы выделить Waldo:

введите описание изображения здесь