我要怎么才能找到Waldo?

这在周末困扰着我:使用数学(图像处理和其他功能)解决那些沃尔多在哪?[北美以外的沃利]难题的好方法是什么?

这是我到目前为止所拥有的,一个通过调光来降低视觉复杂性的函数一些非红色的颜色:

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"]

(瓦尔多在收银机旁):

原始图像

数学图形

270629 次浏览

我找到沃尔多了!

找到了瓦尔多

我是怎么做到的

首先,我过滤掉所有不是红色的颜色

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

接下来,我用一个简单的黑白图案计算这个图像的相关性,以找到衬衫中的红色和白色过渡。

corr = ImageCorrelate[red,Image@Join[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]]

我的猜测是“防弹的方法”(想想中央情报局随时在任何卫星图像中找到沃尔多,而不仅仅是一张没有竞争元素的单一图像,比如条纹衬衫)……我会在沃尔多的许多图像上训练一个玻尔兹曼机——他坐、站、遮挡的所有变化;衬衫、帽子、相机,以及所有的作品。你不需要大量的沃尔多语料库(也许3-5张就足够了),但越多越好。

这将为以任何正确排列发生的各种元素分配概率云,然后确定(通过分割)平均物体大小,将源图像分割成最像个体的物体单元(考虑可能的遮挡和姿势变化),但由于沃尔多照片通常包括很多规模大致相同的人,这应该是一项非常简单的任务,然后将这些片段喂给预训练的玻尔兹曼机器。它将给你每个人都是沃尔多的概率。取概率最高的一个。

这就是今天OCR、邮政编码阅读器和无笔划手写识别的工作方式。基本上你知道答案就在那里,你或多或少地知道它应该是什么样子,其他一切都可能有共同的元素,但绝对是“不是它”,所以你不用担心“不是它”,你只需在所有可能的“它”中寻找“它”的可能性你以前见过”(例如,在邮政编码中,你训练BM只有1秒,只有2秒,只有3秒,等等,然后将每个数字提供给每个机器,并选择一个最有信心的数字)。这比单个神经网络学习所有数字的特征要好得多。

我不知道数学 . . . 太差。但我喜欢上面的答案,在很大程度上。

依靠条纹独自来收集答案仍然存在一个主要缺陷(我个人对一个手动调整没有问题)。有一个例子(由Brett冠军列出,这里)展示,表明他们有时会打破衬衫图案。所以它变成了一个更复杂的图案。

我会尝试一种形状ID和颜色的方法,以及空间关系。就像人脸识别一样,你可以以一定的比例相互寻找几何图案。需要注意的是,通常这些形状中的一个或多个会被遮挡。

在图像上获取白平衡,从图像中获取红色的红平衡。我相信Waldo总是相同的值/色调,但图像可能来自扫描,或者是错误的副本。然后总是引用Waldo实际是的颜色数组:红色、白色、深棕色、蓝色、桃色、{鞋子颜色}。

有一个衬衫图案,还有裤子、眼镜、头发、脸、鞋子和帽子,这些都定义了沃尔多。此外,相对于图像中的其他人,沃尔多是瘦的一面。

因此,随机查找人以获得此图片中人的身高。在图像中的随机点测量一堆事物的平均高度(简单的轮廓会产生相当多的个人)。如果每个事物彼此之间的均方差不在某个范围内,则暂时忽略它们。将平均高度与图像的高度进行比较。如果比例太大(例如,1:2,1:4或类似接近),则重试。运行10次以确保样本都非常接近,不包括任何超出某些均方差的平均值。在数学中可能吗?

这是你的Waldo尺寸。W也很瘦,所以你要找的是5:1或6:1(或其他什么)的ht: wd。然而,这还不够。如果Waldo部分隐藏,高度可能会改变。所以,你要找一块大约2:1的红白相间的块。但必须有更多的指标。

  1. 沃尔多有眼镜。搜索红白上方0.5:1的两个圆圈。
  2. 蓝色裤子。任何数量的蓝色在相同宽度内的任何距离之间的红白末端和他的脚的距离。注意,他穿着他的衬衫短,所以脚不太近。
  3. 帽子。红白相间,任何距离都可以达到他头顶的两倍。注意下面一定有深色的头发,可能还有眼镜。
  4. 长袖。从主红色到白色的某个角度的红白色。
  5. 深色头发。
  6. 鞋子的颜色。我不知道颜色。

这些都可以适用。这些也是对照片中类似人的负面检查--例如,2号不穿红白围裙(离鞋子太近),5号不穿浅色头发。此外,形状只是这些测试中每一个的一个指标 . . . 在指定距离内的颜色单独可以给出好的结果。

这将缩小要处理的区域。

存储这些结果将生成一组应该包含Waldo的区域。排除所有其他区域(例如,对于每个区域,选择一个两倍于普通人大小的圆),然后运行@Heike制定的删除除红色之外的所有区域的过程,依此类推。

对如何编码有什么想法吗?


编辑:

关于如何编码这个 . . . 排除除了沃尔多红色以外的所有区域,将红色区域骨架化,并将它们修剪到一个点。对沃尔多头发棕色、沃尔多裤子蓝色、沃尔多鞋子颜色也这样做。对于沃尔多肤色,排除,然后找到轮廓。

接下来,排除非红色,扩大(很多)所有红色区域,然后骨架化和修剪。这部分将给出可能的沃尔多中心点列表。这将是比较所有其他沃尔多颜色部分的标记。

从这里开始,使用红色区域(不是放大的区域),计算每个区域中的线条。如果有正确的数字(四,对吗?),这肯定是一个可能的区域。如果没有,我想就排除它(作为沃尔多中心 . . . 它可能仍然是他的帽子)。

然后检查上面有没有脸型,上面有没有发点,下面有没有裤子点,下面有没有鞋子点,以此类推。

还没有代码——仍在阅读文档。

我同意@GregoryKlopper的观点,解决在任意图像中找到沃尔多(或任何感兴趣的物体)这一一般问题的0种方法是训练有监督的机器学习分类器。使用许多正负标记的例子,像支持向量机提升决策树桩或玻尔兹曼机器这样的算法很可能被训练来在这个问题上达到高精度。数学甚至在它的机器学习框架中包含了这些算法。

训练Waldo分类器的两个挑战是:

  1. 确定正确的图像特征变换。这就是@Heike的答案有用的地方:红色滤波器和剥离模式检测器(例如小波或DCT分解)将是将原始像素转换为分类算法可以学习的格式的好方法。还需要评估图像所有子部分的基于块的分解……但这更容易,因为Waldo a)总是大致相同的大小,b)总是在每张图像中出现一次。
  2. 获取足够的训练样本。SVM在每个类至少有100个样本的情况下工作得最好。增强的商业应用(例如,数码相机中的面部对焦)是在数百万个正面和负面样本上训练的。

一个快速的google图片搜索出现了一些好的数据——我将尝试收集一些训练示例并立即编写它!

然而,即使是机器学习方法(或@iND建议的基于规则的方法)也会为像沃尔多斯的土地

我有一个使用OpenCV找到Waldo的快速解决方案。

我使用OpenCV中可用的模板匹配函数来查找Waldo。

为此,需要一个模板。所以我从原始图像中裁剪了Waldo并将其用作模板。

在此处输入图片描述

接下来,我调用cv2.matchTemplate()函数和归一化相关系数作为使用的方法。它在单个区域返回一个高概率,如下面的白色所示(在左上角区域的某个地方):

在此处输入图片描述

使用cv2.minMaxLoc()函数找到最高可能区域的位置,然后我用它绘制矩形以突出显示Waldo:

在此处输入图片描述