[英]How do I find Waldo with Mathematica?
这个周末一直困扰着我:有什么好方法可以解决沃尔多在哪里? [北美以外的'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 在收银台旁边):
我找到了沃尔多!
我是怎么做到的
首先,我过滤掉所有不是红色的颜色
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]]
我对“防弹方法”的猜测(想想中央情报局随时在任何卫星图像中找到沃尔多,而不仅仅是没有竞争元素的单一图像,如条纹衬衫)......我会在沃尔多的许多图像上训练玻尔兹曼机- 他坐、站、闭等的所有变化; 衬衫、帽子、相机和所有作品。 您不需要大量的 Waldos 语料库(也许 3-5 个就足够了),但越多越好。
这将为以任何正确排列发生的各种元素分配概率云,然后(通过分割)确定平均对象大小是多少,将源图像分割成最类似于个人的对象单元格(考虑可能的遮挡和姿势变化) ),但由于 Waldo 图片通常包含大量相同比例的人,这应该是一项非常容易的任务,然后将这些片段输入预训练的 Boltzmann 机器。 它会给你每个人都是 Waldo 的概率。 取一个概率最高的。
这就是 OCR、邮政编码阅读器和无笔划手写识别今天的工作方式。 基本上你知道答案就在那里,你或多或少知道它应该是什么样子,其他一切可能都有共同的元素,但绝对是“不是它”,所以你不用为“不是它”而烦恼,你只需在您之前见过的所有可能的“它”中查看“它”的可能性(例如,在邮政编码中,您只需将 BM 训练 1 秒、2 秒、3 秒等,然后输入每个数字到每台机器,然后选择一个最有信心的。这比单个神经网络学习所有数字的特征要好得多。
我同意@GregoryKlopper 的观点,即解决在任意图像中找到 Waldo(或任何感兴趣的对象)的一般问题的正确方法是训练有监督的机器学习分类器。 使用许多正标记和负标记示例,可以训练诸如支持向量机、增强决策树桩或玻尔兹曼机之类的算法,以在此问题上实现高精度。 Mathematica 甚至将这些算法包含在其 机器学习框架中。
训练 Waldo 分类器的两个挑战是:
快速的谷歌图片搜索会找到一些很好的数据——我将尝试收集一些训练示例并立即对其进行编码!
然而,即使是机器学习方法(或@iND 建议的基于规则的方法)也很难获得像沃尔多斯土地这样的图像!
我不知道 Mathematica 。 . . 太糟糕了。 但在大多数情况下,我喜欢上面的答案。
还有在单独依靠搜集答案条纹的一大缺陷(我个人没有一个手动调节的一个问题)。 有一个例子(由 Brett Champion 列出, 这里)表明他们有时会破坏衬衫的图案。 那么它就变成了一个更复杂的模式。
我会尝试使用形状 ID 和颜色以及空间关系的方法。 就像人脸识别一样,您可以寻找彼此之间具有特定比例的几何图案。 需要注意的是,这些形状中的一个或多个通常会被遮挡。
在图像上获得白平衡,从图像中获得红色平衡。 我相信 Waldo 总是具有相同的值/色调,但图像可能来自扫描件,或者是坏的副本。 然后总是参考 Waldo 实际上是的一系列颜色:红色、白色、深棕色、蓝色、桃色、{鞋色}。
有衬衫图案,还有定义 Waldo 的裤子、眼镜、头发、脸、鞋子和帽子。 此外,相对于图像中的其他人,Waldo 偏瘦。
所以,找随机的人来获得这张照片中人的身高。 测量图像中随机点一堆东西的平均高度(一个简单的轮廓会产生相当多的个体)。 如果每件事都没有在彼此之间的某个标准偏差内,则暂时将其忽略。 将高度的平均值与图像的高度进行比较。 如果比率太大(例如,1:2、1:4 或类似的接近),则再试一次。 运行它 10(?) 次以确保样本都非常接近,排除超出某个标准偏差的任何平均值。 在 Mathematica 中可能吗?
这是你的 Waldo 尺寸。 沃尔斯很瘦,所以你正在寻找 5:1 或 6:1(或其他)ht:wd 的东西。 然而,这还不够。 如果 Waldo 部分隐藏,则高度可能会发生变化。 因此,您正在寻找一个 ~2:1 的红白块。 但必须有更多的指标。
其中任何一个都可以申请。 这些也是对图片中类似人的负面检查——例如,#2 否定穿着红白色围裙(太靠近鞋子),#5 消除浅色头发。 此外,形状只是这些测试中的每一个的一个指标。 . . 在指定的距离内单独使用颜色可以产生很好的效果。
这将缩小要处理的区域。
存储这些结果将产生一组应该有 Waldo 的区域。 排除所有其他区域(例如,对于每个区域,选择一个两倍于平均人大小的圆圈),然后运行@Heike 制定的过程,删除除红色之外的所有区域,依此类推。
关于如何编码的任何想法?
编辑:
关于如何编码的想法。 . . 排除 Waldo red 以外的所有区域,将红色区域骨架化,并将它们修剪成一个点。 对 Waldo 头发棕色、Waldo 裤子蓝色、Waldo 鞋颜色执行相同操作。 对于 Waldo 肤色,排除,然后找到轮廓。
接下来,排除非红色,扩大(大量)所有红色区域,然后骨架化和修剪。 这部分将列出可能的 Waldo 中心点。 这将是与所有其他 Waldo 颜色部分进行比较的标记。
从这里开始,使用骨架化的红色区域(不是扩张的区域),计算每个区域中的线条。 如果有正确的数字(四个,对吗?),这肯定是一个可能的区域。 如果没有,我想就排除它(作为沃尔多中锋......它可能仍然是他的帽子)。
然后检查是否有上面的脸型,上面的头发点,下面的裤子点,下面的鞋子点等等。
还没有代码——仍在阅读文档。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.