numpy - 找到一组像素附近的所有像素

numpy - find all pixels near a set of pixels

我有一个 PIL.Image 对象 input 模式 '1' (黑白位图),我想确定图像中的每个像素是否在任何白色像素的 n 像素(欧氏距离 - n 可能约为 100 左右)。

动机是:input 代表两个其他图像之间不同的每个像素,我想在所有这些差异周围创建一个高亮区域,以清楚地显示差异发生的位置。

到目前为止,我还没有找到一个快速的算法来解决这个问题——下面的代码可以工作,但是卷积速度很慢,因为 kernel 参数比卷积显然可以有效处理的要大:

from scipy import ndimage
import numpy as np
from PIL import Image

n = 100
y, x = np.ogrid[:2*n, :2*n]
kernel = (x-n)**2 + (y-n)**2 <= n**2

img = Image.open('input.png')
result = ndimage.convolve(np.array(img), kernel) != 0
Image.fromarray(result).save('result.png')

示例输入 input.png:

所需的输出 result.png(这里还有一些我认为来自 over/underflow 的不需要的工件):

即使是这些小图像,计算也需要 30 秒左右。 有人可以推荐一个更好的程序来计算这个吗?谢谢。

ndimage.convolve 使用非常低效的算法 执行卷积当然 运行 in O(n m kn km) 其中 (n,m) 是形状图像的形状,(kn, km) 是内核的形状。您可以 使用 FFTO(n m log(n m)) 时间内更有效地完成这项工作。希望 scipy 提供这样的功能。这是一个用法示例:

import scipy.signal
import numpy as np
from PIL import Image

n = 100
y, x = np.ogrid[:2*n, :2*n]
kernel = (x-n)**2 + (y-n)**2 <= n**2

img = Image.open('input.png')
result = scipy.signal.fftconvolve(img, kernel, mode='same') >= 1.0
Image.fromarray(result).save('result.png')

这在我的机器上 >500 倍 并且这也修复了人工制品。这是结果: