首页 文章

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

提问于
浏览
1524

周末这让我感到烦恼:使用Mathematica(图像处理和其他功能)解决这些问题的好方法是什么?#2694995_ ['Wally'北美之外]谜题?

这是我到目前为止的功能,它通过调暗一些非红色来减少视觉复杂度:

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

5 回答

  • 46

    我不知道Mathematica . . . 太糟糕了 . 但在大多数情况下,我喜欢上面的答案 .

    仍然存在一个重大缺陷,仅依靠条纹来收集答案(我个人对一次手动调整没有问题) . 有一个例子(由Brett Champion列出,here),这表明他们有时打破了衬衫模式 . 那么它就变成了一个更复杂的模式 .

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

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

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

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

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

    • Waldo戴眼镜 . 在红白色上方搜索0.5:1的两个圆圈 .

    • 蓝裤子 . 在红白色的末端和到他的脚的距离之间的任何距离内的任何数量的蓝色 . 请注意,他穿着衬衫短,所以脚不太靠近 .

    • 帽子 . 红白色任何距离,最高可达头顶两倍 . 请注意,下面必须有深色头发,可能还有眼镜 .

    • 长袖 . 从主红白色的某个角度看的红白色 .

    • 深色头发 .

    • 鞋色 . 我不知道颜色 .

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

    这将缩小要处理的范围 .

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

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


    编辑:

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

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

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

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

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

  • 40

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

    我使用OpenCV中提供的 template matching 函数来查找Waldo .

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

    接下来,我将 cv2.matchTemplate() 函数与 normalized correlation coefficient 一起调用为所使用的方法 . 它的概率很高在单个区域,如下面的白色所示(左上角区域的某处):

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

  • 141

    我猜想"bulletproof way to do this"(想想CIA随时在任何卫星图像中发现Waldo,而不仅仅是没有竞争元素的单个图像,比如条纹衬衫)......我会在Waldo的许多图像上训练一个Boltzmann machine - 他坐着的所有变种,站立,闭塞等;衬衫,帽子,相机和所有的作品 . 你不需要大量的Waldos(也许3-5就够了),但越多越好 .

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

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

  • 2

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

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

    • 确定正确的图像特征变换 . 这是@Heike的答案有用的地方:红色滤镜和剥离图案检测器(例如,小波或DCT分解)将是将原始像素转换为分类算法可以学习的格式的好方法 . 还需要一个基于块的分解来评估图像的所有子部分......但是由于Waldo a)总是大致相同的大小并且b)在每个图像中始终只出现一次,因此这变得更容易 .

    • 获得足够的训练样例 . SVM最适合每个类至少100个示例 . 增强的商业应用(例如,数字相机中的面部聚焦)在数百万个正面和负面示例上进行训练 .

    快速Google image search发现了一些好的数据 - 我将收集一些培训示例并立即对其进行编码!

    然而,即使是机器学习方法(或@iND建议的基于规则的方法)也会为像Land of Waldos这样的图像而烦恼!

  • 1629

    我找到了沃尔多!

    waldo had been found

    How I've done it

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

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

相关问题