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是收银台):

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)
Gre*_*per 143
我猜测"做到这一点的防弹方式"(想想CIA随时在任何卫星图像中找到Waldo,而不仅仅是没有竞争元素的单个图像,如条纹衬衫)......我会在Waldo的许多图像上训练Boltzmann机器 - 他坐着,站立,闭塞等各种变化; 衬衫,帽子,相机和所有的作品.你不需要大量的Waldos(也许3-5就够了),但越多越好.
这会将概率云分配给以正确排列方式出现的各种元素,然后建立(通过分割)平均对象大小是什么,将源图像分割成最类似于个体的对象的单元格(考虑可能的遮挡和姿势变化) ),但由于Waldo图片通常包含大量相同比例的人,这应该是一项非常简单的任务,然后为预先训练好的Boltzmann机器提供这些部分.它会给你每个人成为Waldo的概率.以最高概率获得一个.
这就是今天OCR,邮政编码阅读器和无笔划手写识别的工作原理.基本上你知道答案就在那里,你或多或少知道它应该是什么样的,其他一切都可能有共同的元素,但绝对是"不是它",所以你不要打扰"不是它",你只看一下你之前看过的所有可能"它"中"它"的可能性"(例如,在邮政编码中,你只训练BM 1s,只需2s,只需3s等,然后喂每个数字到每台机器,并选择一个最有信心的.)这比所有数字的单个神经网络学习功能好很多.
lub*_*bar 46
我同意@GregoryKlopper的意见,解决在任意图像中找到Waldo(或任何感兴趣的对象)的一般问题的正确方法是训练有监督的机器学习分类器.使用许多正面和负面标记的示例,可以训练诸如支持向量机,Boosted Decision Stump或Boltzmann Machine 的算法以在该问题上实现高精度.Mathematica甚至在其机器学习框架中包含了这些算法.
培训Waldo分类器的两个挑战是:
一个快速的谷歌图像搜索提供了一些好的数据 - 我将去收集一些培训示例并立即对其进行编码!
然而,即使是机器学习方法(或@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的红白色块.但必须有更多的指标.
任何这些都可以适用.这些也是对照中类似人物的负面检查 - 例如,#2否定穿着红白色的围裙(太靠近鞋子),#5消除浅色头发.此外,形状只是每个测试的一个指标...在指定距离内单独使用颜色可以产生良好的效果.
这将缩小要处理的范围.
存储这些结果将产生一组应该包含Waldo 的区域.排除所有其他区域(例如,对于每个区域,选择一个两倍于一般人的大小的圆圈),然后运行@Heike布局的过程除去除红色之外的所有区域,依此类推.
有关如何编码的任何想法?
编辑:
关于如何编码的想法...排除除Waldo红色之外的所有区域,对红色区域进行镂空,并将它们修剪为单个点.同样适用于Waldo棕色头发,Waldo裤子蓝色,Waldo鞋子颜色.对于Waldo肤色,排除,然后找到轮廓.
接下来,排除所有红色区域的非红色,扩张(很多),然后进行骨架化和修剪.这部分将列出可能的沃尔多中心点.这将是比较所有其他Waldo颜色部分的标记.
从这里开始,使用镂空的红色区域(不是扩张的区域),计算每个区域的线条.如果有正确的数字(四个,对吗?),这肯定是一个可能的区域.如果没有,我想只是排除它(作为一个沃尔多中心......它可能仍然是他的帽子).
然后检查上面是否有脸形,上方有发点,裤子指向下方,鞋点位于下方,等等.
还没有代码 - 仍在阅读文档.
我有一个使用 OpenCV 查找 Waldo 的快速解决方案。
我使用OpenCV 中提供的模板匹配功能来找到 Waldo。
为此,需要一个模板。所以我从原始图像中裁剪了 Waldo 并将其用作模板。
接下来,我将该cv2.matchTemplate()函数与归一化相关系数一起调用作为所使用的方法。它在单个区域返回了高概率,如下图白色所示(位于左上角区域的某个位置):
使用函数找到了最高可能区域的位置cv2.minMaxLoc(),然后我用它来绘制矩形以突出显示 Waldo: