如何用Python找到沃利?

85 投票
7 回答
23254 浏览
提问于 2025-04-17 10:10

毫不掩饰地加入这个话题 :-)

受到 如何用Mathematica找到沃尔多 和后续的 如何用R找到沃尔多 的启发,作为一个新的Python用户,我很想看看这该怎么做。看起来Python在这方面比R更合适,而且我们不需要像使用Mathematica或Matlab那样担心许可证的问题。

在下面这样的例子中,显然仅仅使用条纹是行不通的。如果能找到一种简单的基于规则的方法来处理像这样的难例,那就太有意思了。

在海滩上

我添加了[machine-learning]标签,因为我相信正确的答案需要使用机器学习技术,比如Gregory Klopper在原帖中提到的限制玻尔兹曼机(RBM)方法。这里有一些 Python中的RBM代码,这可能是一个不错的起点,但显然需要训练数据来支持这种方法。

2009年IEEE国际信号处理机器学习研讨会(MLSP 2009)上,他们举办了一个 数据分析竞赛:沃尔多在哪里?。训练数据是以Matlab格式提供的。请注意,该网站上的链接已经失效,但数据(以及Sean McLoone及其同事采用的方法的来源)可以在 这里找到(查看SCM链接)。看起来这是一个不错的起点。

7 个回答

2

也许你可以先把这个问题分成两个更小的问题:

  1. 先想办法把人和背景分开。
  2. 然后用尽可能多的正面和负面例子来训练一个神经网络分类器。

不过,这两个问题依然很大,很难解决……

顺便说一下,我会选择C++和OpenCV,这样的工具看起来更适合这个任务。

2

你可以试试模板匹配,也就是找出和你要的东西最相似的那个,然后再用机器学习来进一步缩小范围。不过这也很难,因为模板匹配的准确性可能不高,可能会把每张脸或者像脸的图片都找出来。我觉得如果你想要稳定地做到这一点,可能需要的不仅仅是机器学习。

66

这里有一个使用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)

最后,我们得到了 waldo

撰写回答