如何用Python找到沃利?
毫不掩饰地加入这个话题 :-)
受到 如何用Mathematica找到沃尔多 和后续的 如何用R找到沃尔多 的启发,作为一个新的Python用户,我很想看看这该怎么做。看起来Python在这方面比R更合适,而且我们不需要像使用Mathematica或Matlab那样担心许可证的问题。
在下面这样的例子中,显然仅仅使用条纹是行不通的。如果能找到一种简单的基于规则的方法来处理像这样的难例,那就太有意思了。
我添加了[machine-learning]标签,因为我相信正确的答案需要使用机器学习技术,比如Gregory Klopper在原帖中提到的限制玻尔兹曼机(RBM)方法。这里有一些 Python中的RBM代码,这可能是一个不错的起点,但显然需要训练数据来支持这种方法。
在 2009年IEEE国际信号处理机器学习研讨会(MLSP 2009)上,他们举办了一个 数据分析竞赛:沃尔多在哪里?。训练数据是以Matlab格式提供的。请注意,该网站上的链接已经失效,但数据(以及Sean McLoone及其同事采用的方法的来源)可以在 这里找到(查看SCM链接)。看起来这是一个不错的起点。
7 个回答
也许你可以先把这个问题分成两个更小的问题:
- 先想办法把人和背景分开。
- 然后用尽可能多的正面和负面例子来训练一个神经网络分类器。
不过,这两个问题依然很大,很难解决……
顺便说一下,我会选择C++和OpenCV,这样的工具看起来更适合这个任务。
你可以试试模板匹配,也就是找出和你要的东西最相似的那个,然后再用机器学习来进一步缩小范围。不过这也很难,因为模板匹配的准确性可能不高,可能会把每张脸或者像脸的图片都找出来。我觉得如果你想要稳定地做到这一点,可能需要的不仅仅是机器学习。
这里有一个使用mahotas的实现。
from pylab import imshow
import numpy as np
import mahotas
wally = mahotas.imread('DepartmentStore.jpg')
wfloat = wally.astype(float)
r,g,b = wfloat.transpose((2,0,1))
把图像分成红色、绿色和蓝色三个通道。为了更好地计算,我们在开始时把它们转换成浮点数。
w = wfloat.mean(2)
w
是白色通道。
pattern = np.ones((24,16), float)
for i in xrange(2):
pattern[i::4] = -1
在垂直方向上构建一个模式,内容是+1,+1,-1,-1。这就是沃尔多的衬衫。
v = mahotas.convolve(r-w, pattern)
用红色通道减去白色通道进行卷积。这会在衬衫的地方产生强烈的反应。
mask = (v == v.max())
mask = mahotas.dilate(mask, np.ones((48,24)))
寻找最大值并进行膨胀处理,这样它就会变得更明显。接下来,我们会降低整个图像的亮度,除了我们感兴趣的区域:
wally -= .8*wally * ~mask[:,:,None]
imshow(wally)
最后,我们得到了 !