如何用MathematicafindWaldo?

这是在周末给我打扰:什么是解决那些Waldo的好方法 使用Mathematica(image processing和其他function)的[北美以外的Wally ]谜题?

这是我迄今为止的function,通过调暗一些非红色的颜色来减less视觉复杂度:

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图形

我find了沃尔多!

沃尔多已被发现

我是如何做到的

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

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

接下来,我正在计算这个图像与简单的黑白图案的相关性,以find衬衫中的红色和白色的过渡。

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

我的猜测是用“防弹的方式来做到这一点”(想想中情局随时可以find任何卫星图像的沃尔多,而不是像没有竞争的单一图像,比如条纹衬衫)…我会在沃尔多的许多图像上训练玻尔兹曼机器 – 他的所有变化,坐着,站立,闭塞等; 衬衫,帽子,相机和所有的作品。 你不需要大量的瓦尔多斯语料库(大概3-5个就足够了),但是越多越好。

这将为任何正确排列的各种元素分配概率云,然后build立(通过分割)一个平均物体大小是什么,将源图像分割成最相似于个体的物体的细胞(考虑可能的遮挡和姿态变化),但是由于沃尔多的照片通常包含了大量的人,大小相当,这应该是一个非常简单的任务,然后喂养预先训练的玻尔兹曼机器的这些部分。 它会给你每个人的概率是沃尔多。 以最高的概率拿一个。

这就是OCR,ZIP代码阅读器和无笔迹手写识别今天的工作原理。 基本上你知道答案就在那里,你应该知道它应该是什么样子,其他的可能有共同的元素,但肯定是“不是”,所以你不用担心“不是”,你只是看看所有可能的“它”在你以前见过的所有可能的“它”的可能性(例如,在邮政编码,例如,你训练BM只有1秒,只有2秒,只有3秒等等,然后喂数字到每台机器,并select一个最有信心)。这比一个单一的neural network学习所有数字的function要好得多。

我同意@GregoryKlopper,解决在任意图像中findWaldo(或任何感兴趣对象)的一般问题的正确方法是训练一个有监督的机器学习分类器。 使用许多正面和负面的标记示例, 支持向量机 , Boosted Decision Stump或Boltzmann Machine等algorithm可能会被训练以在这个问题上达到高精度。 Mathematica甚至在其机器学习框架中包含这些algorithm。

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

  1. 确定正确的图像特征变换。 这就是@ Heike的答案是有用的:红色滤波器和剥离模式检测器(例如,小波或DCT分解)将是将原始像素转换为分类algorithm可以学习的格式的好方法。 评估图像所有子部分的基于块的分解也将是必需的,但是由于Waldo总是大致相同的大小以及b)总是在每个图像中总是呈现一次,所以这更容易。
  2. 获得足够的训练实例。 支持向量机在每个类中至less有100个例子是最好的。 增强的商业应用(例如数码相机中的面部聚焦)在数百万个正面和负面的例子中被训练。

一个快速的谷歌图片search出现了一些好的数据 – 我将去收集一些训练的例子,现在编码!

然而,即使是机器学习的方法(或者@iND提出的基于规则的方法)也会为像沃尔多斯之地这样的形象而奋斗 !

我不知道Mathematica。 。 。 太糟糕了。 但是我最喜欢上面的答案。

依靠单独的条纹来收集答案还有一个主要的缺陷(我个人没有一个手动调整的问题)。 有一个例子(由Brett Champion列在这里 )介绍,这表明他们有时打破了衬衫的模式。 那么它就变成了一个更复杂的模式。

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

在图像上获得白平衡,并从图像中红色平衡。 我相信,沃尔多永远是一样的价值/色调,但形象可能来自扫描,或者是一个坏的副本。 然后总是提到Waldo实际上的一系列颜色:红色,白色,深褐色,蓝色,桃子,{鞋子颜色}。

有一个衬衫模式,还有裤子,眼镜,头发,脸,鞋和帽子,定义沃尔多。 而且,相对于形象中的其他人来说,沃尔多是瘦骨side </s>的。

所以,find随机的人来获得这张照片中的人的身高。 测量图像中随机点的一堆东西的平均高度(一个简单的轮廓将产生不less个别人)。 如果每个事物都不在相互之间的某个标准偏差之内,那么现在就忽略它们。 比较高度的平均值与图像的高度。 如果比例过高(例如,1:2,1:4或类似的closures),则再试一次。 运行10(?)次,以确保样本都非常接近,不包括任何超出某个标准偏差的平均值。 可能在Mathematica?

这是你的沃尔多尺寸。 沃尔索是瘦,所以你正在寻找东西5:1或6:1(或其他)ht:wd。 但是,这是不够的。 如果沃尔多部分隐藏,高度可能会改变。 所以,你正在寻找一块〜2:1的红白色。 但是必须有更多的指标。

  1. 沃尔戴眼镜。 在红白色之上search0.5:1的两个圆圈。
  2. 蓝色的裤子。 在红白色的结束和到他的脚的距离之间的任何距离内的相同宽度的任何量的蓝色。 请注意,他穿短衬衫,所以脚不是太靠近。
  3. 帽子。 红白的任何距离都可以达到他头顶的两倍。 请注意,它必须有黑色的头发,可能是眼镜。
  4. 长袖。 从主要的红白色的某个angular度红白色。
  5. 黑发。
  6. 鞋子的颜色。 我不知道颜色。

任何这些都可以适用。 这些也是对照片中类似人物的负面检查 – 例如,#2否定穿着红白色围裙(太接近鞋子),#5消除浅色头发。 而且,形状只是这些testing的一个指标。 。 。 在指定的距离内单独的颜色可以给出良好的结果。

这将缩小要处理的区域。

存储这些结果将产生一组应该有Waldo的区域。 排除所有其他区域(例如,对于每个区域,select一个比普通人大两倍的圆圈),然后运行@ Heike所展示的过程,除去除红色之外的所有区域,等等。

任何想法如何编码?


编辑:

关于如何编码的想法。 。 。 排除所有地区,但沃尔多红色,骨架红色地区,并将其修剪到一个点。 对Waldo发棕色,Waldo裤子蓝色,Waldo鞋子颜色也一样。 对于沃尔多肤色,排除,然后find轮廓。

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

从这里,使用骷髅红色区域(而不是扩大的),计算每个区域的线条。 如果有正确的数字(四,对吧?),这当然是一个可能的地方。 如果不是的话,我想只是把它排除在外(作为一个沃尔多中心……它可能仍然是他的帽子)。

然后检查是否有上面的脸型,上面的发点,下面的裤子点,下面的鞋点等等。

没有代码 – 仍然阅读文档。

我有一个使用OpenCVfindWaldo的快速解决scheme。

我使用了OpenCV中的模板匹配function来查找Waldo。

要做到这一点,需要一个模板(杜…)。 所以我从原始图像中剪下了沃尔多,并将其用作模板。

在这里输入图像说明

接下来,我将cv2.matchTemplate()函数与标准化相关系数一起作为所使用的方法。 它在单个区域返回的概率很高,如下面的白色(左上angular区域的某处)所示:

在这里输入图像说明

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

在这里输入图像说明