我怎样才能找到带有Mathematica的Waldo?

Arn*_*ing 1538 wolfram-mathematica image-processing

周末这让我很烦恼:什么是解决那些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}]
]
Run Code Online (Sandbox Code Playgroud)

以及这个"有效"的网址示例:

whereIsWaldo["http://www.findwaldo.com/fankit/graphics/IntlManOfLiterature/Scenes/DepartmentStore.jpg"]
Run Code Online (Sandbox Code Playgroud)

(Waldo是收银台):

Mathematica图形

Hei*_*ike 1636

我找到了沃尔多!

沃尔多被发现了

我是怎么做到的

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

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

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

corr = ImageCorrelate[red, 
   Image@Join[ConstantArray[1, {2, 4}], ConstantArray[0, {2, 4}]], 
   NormalizedSquaredEuclideanDistance];
Run Code Online (Sandbox Code Playgroud)

Binarize用来挑选图像中具有足够高相关性的像素,并在它们周围画出白色圆圈以强调它们Dilation

pos = Dilation[ColorNegate[Binarize[corr, .12]], DiskMatrix[30]];
Run Code Online (Sandbox Code Playgroud)

我不得不在水平上玩一点.如果水平太高,则挑选出太多误报.

最后,我将此结果与原始图像组合以获得上述结果

found = ImageMultiply[waldo, ImageAdd[ColorConvert[pos, "GrayLevel"], .5]]
Run Code Online (Sandbox Code Playgroud)

  • 你似乎误解了Where's Waldo的规则.这显然是*作弊. (155认同)
  • 虽然这是一个很好的黑客,但它不起作用.它需要手动调整,仅适用于一个图像.我不明白为什么这个被投票,甚至被选为答案.它甚至不鼓励其他人试图用更好的工作方法来回答. (91认同)
  • @MikeBantegui虽然Heike的解决方案很棒,但我不会那么快将它打包成`WhereIsWaldo`函数,因为它不是一般的解决方案.海克本人已经指出,在你获得积极的成果之前,需要先发挥水平.要了解我的意思,请尝试使用"http://www.findwaldo.com/fankit/graphics/IntlManOfLiterature/Scenes/AtTheBeach.jpg"中的打包功能."这个更难. (52认同)
  • 请参阅此Meta帖子:http://meta.stackexchange.com/questions/116401/stack-overflow-tioned-on-nprs-wait-wait-dont-tell-me-and-ny-times (33认同)
  • 这个图像比较棘手:[Waldo](http://www.findwaldo.com/fankit/graphics/IntlManOfLiterature/Scenes/TheGobblingGluttons.jpg).我认为,有一些可以突出潜在Waldos的东西仍然有用(对于'有用'的一些定义.)(这让我想起了iPhoto有时会在我们的照片集中识别出来的一些东西...) (17认同)
  • 作为一个沃尔多,我自己,我赞成这个答案 (16认同)
  • Downvoted,因为这不是一般解决方案. (15认同)
  • 您是否考虑过使用Waldo作为模板而不是红白条纹?很多次,红白条纹被用来混淆搜索:) (6认同)
  • 嗯...那不是沃尔多.Waldo穿着真空推销员(你必须仔细观察,但那就是他). (6认同)
  • 你的老板现在知道你在做什么吗? (4认同)
  • 我没有Mathematica许可证和300欧元只是为了玩图像处理工具包似乎有点贵......也许我稍后会尝试使用opencv. (3认同)
  • @Brett 我不寒而栗地想象这些事情...... ;-) (2认同)
  • 然后你看到你的"算法解决"地狱:http://trezoid.com/gubbins/WallyHell.jpg(真正的那个实际上是在那个图像的右下角) (2认同)

Gre*_*per 143

我猜测"做到这一点的防弹方式"(想想CIA随时在任何卫星图像中找到Waldo,而不仅仅是没有竞争元素的单个图像,如条纹衬衫)......我会在Waldo的许多图像上训练Boltzmann机器 - 他坐着,站立,闭塞等各种变化; 衬衫,帽子,相机和所有的作品.你不需要大量的Waldos(也许3-5就够了),但越多越好.

这会将概率云分配给以正确排列方式出现的各种元素,然后建立(通过分割)平均对象大小是什么,将源图像分割成最类似于个体的对象的单元格(考虑可能的遮挡和姿势变化) ),但由于Waldo图片通常包含大量相同比例的人,这应该是一项非常简单的任务,然后为预先训练好的Boltzmann机器提供这些部分.它会给你每个人成为Waldo的概率.以最高概率获得一个.

这就是今天OCR,邮政编码阅读器和无笔划手写识别的工作原理.基本上你知道答案就在那里,你或多或少知道它应该是什么样的,其他一切都可能有共同的元素,但绝对是"不是它",所以你不要打扰"不是它",你只看一下你之前看过的所有可能"它"中"它"的可能性"(例如,在邮政编码中,你只训练BM 1s,只需2s,只需3s等,然后喂每个数字到每台机器,并选择一个最有信心的.)这比所有数字的单个神经网络学习功能好很多.

  • 邮政编码一直与Boltzmann机器一起阅读,邮件传递的准确性已经达到顶峰. (14认同)
  • 那不仅仅是普通的神经网络吗?此外,维基百科文章声称玻尔兹曼机器不实用. (13认同)
  • 没有尝试我不确定,但如果足够大和足够复杂,神经网络应该足够任何东西.特别是对于复发.玻尔兹曼机器非常非常非常好地识别一组相当简单的数据,并且数据海洋中的噪声很大. (2认同)

lub*_*bar 46

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

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

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

一个快速的谷歌图像搜索提供了一些好的数据 - 我将去收集一些培训示例并立即对其进行编码!

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


iND*_*iND 40

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

还有在依靠条纹的一大缺陷独自搜集的答案(我个人不有一个问题一个手动调节).有一个例子(由Brett Champion列出,这里)显示他们有时打破了衬衫模式.那么它就变成了一个更复杂的模式.

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

在图像上获得白平衡,并从图像中红色显示红色.我相信Waldo总是具有相同的值/色调,但图像可能来自扫描或坏的副本.然后总是参考Waldo实际上的颜色数组:红色,白色,深棕色,蓝色,桃色,{鞋色}.

有一种衬衫图案,以及定义Waldo的裤子,眼镜,头发,面部,鞋子和帽子.而且,相对于图像中的其他人,Waldo处于瘦弱的一面.

因此,找到随机的人来获得这张照片中的人的高度.测量图像中随机点的一堆东西的平均高度(简单的轮廓将产生相当多的个人).如果每件事物彼此之间没有标准偏差,则暂时忽略它们.将高度的平均值与图像的高度进行比较.如果比例太大(例如,1:2,1:4,或类似地接近),则再试一次.运行10(?)次以确保样本非常接近,排除任何超出某些标准偏差的平均值.可能在Mathematica?

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

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

任何这些都可以适用.这些也是对照中类似人物的负面检查 - 例如,#2否定穿着红白色的围裙(太靠近鞋子),#5消除浅色头发.此外,形状只是每个测试的一个指标...在指定距离内单独使用颜色可以产生良好的效果.

这将缩小要处理的范围.

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

有关如何编码的任何想法?


编辑:

关于如何编码的想法...排除除Waldo红色之外的所有区域,对红色区域进行镂空,并将它们修剪为单个点.同样适用于Waldo棕色头发,Waldo裤子蓝色,Waldo鞋子颜色.对于Waldo肤色,排除,然后找到轮廓.

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

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

然后检查上面是否有脸形,上方有发点,裤子指向下方,鞋点位于下方,等等.

还没有代码 - 仍在阅读文档.

  • 也许您可以在您熟悉的系统/语言中展示概念证明.这也可以让您了解可能遇到的困难. (8认同)
  • 我没有向你投票,我认为downvotes不适合诚实的回答(除非他们提供错误的信息).downvotes最可能的原因是你似乎没有尝试过(相当复杂的声音)方法,找到一个好的解决方案可能需要进行大量的实际实验并排除许多想法.另一个推测性答案表明过去曾用于类似问题的*一般*方法(作为起点),并且有大量关于它的文献.试图解释发生了什么. (3认同)

Jer*_*uke 6

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

我使用OpenCV 中提供的模板匹配功能来找到 Waldo。

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

在此输入图像描述

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

在此输入图像描述

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

在此输入图像描述

  • 试图解决最著名的图像处理问题?;)你的解决方案很好很简单,但是a/只适用于这个特定的图像,b/需要你想要事先找到的Waldo的确切图像,而我认为问题是在任何“Where's Waldo图像”中找到任何Waldo,例如你会玩正常的游戏:事先不知道他长什么样。无论如何,这个问题很有趣 (9认同)