如何使用Numpy高效地执行最近邻插值
我有一个图像,为了这个问题,它只是一个numpy数组。我想过滤图像以去除孤立透明像素形式的噪声(更一般地说,我也想去除线条,但这是下一个问题) 让我们举一个可玩的例子:如何使用Numpy高效地执行最近邻插值,numpy,image-processing,numpy-slicing,Numpy,Image Processing,Numpy Slicing,我有一个图像,为了这个问题,它只是一个numpy数组。我想过滤图像以去除孤立透明像素形式的噪声(更一般地说,我也想去除线条,但这是下一个问题) 让我们举一个可玩的例子: a = np.ones((10, 10), np.uint8) a[5,5] = 0 # isolated hole a[5,6] = 2 # the neighbour to clone 导致该矩阵: [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1,
a = np.ones((10, 10), np.uint8)
a[5,5] = 0 # isolated hole
a[5,6] = 2 # the neighbour to clone
导致该矩阵:
[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 0, 2, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
问题是,当矩阵中有一个0时,我希望它被最近的邻居替换(在这种情况下是2,但如果易于实现,四个的平均值可能更好)
这可以在没有显式循环的情况下完成吗?使用检测
a
中的0
条目。要计算描述的平均值,请与mode='same'
和以下内核一起使用:
kernel=np.array([[0,1,0],[1,0,1],[0,1,0]])/4
最后,用卷积结果中的相应条目替换a
中找到的0
条目。请参阅以下代码片段:
将numpy导入为np
从scipy.signal导入卷积2D
a=np.ones((10,10),np.uint8)
a[5,5]=0
a[5,6]=2
印刷品(a)
kernel=np.array([[0,1,0],[1,0,1],[0,1,0]])/4
b=卷积2D(a,内核,模式='same')
a[a==0]=b[a==0]
印刷品(a)
结果是:
[[1]
[1 1 1 1 1 1 1 1 1 1]
[1 1 1 1 1 1 1 1 1 1]
[1 1 1 1 1 1 1 1 1 1]
[1 1 1 1 1 1 1 1 1 1]
[1 1 1 1 1 1 2 1 1 1]
[1 1 1 1 1 1 1 1 1 1]
[1 1 1 1 1 1 1 1 1 1]
[1 1 1 1 1 1 1 1 1 1]
[1 1 1 1 1 1 1 1 1 1]]
由于您将a
初始化为np.uint8
,实际替换值1.25
被截断为1
。如果将a
初始化为np.float32
,您将看到1.25
正确地放置在那里
----------------------------------------
系统信息
----------------------------------------
平台:Windows-10-10.0.16299-SP0
Python:3.9.1
NumPy:1.20.1
SciPy:1.6.0
----------------------------------------
编辑:如果只想计算两个/三个相邻像素的平均值,硬编码内核将无法正确处理角点和边界像素。也许,在不进行除法的情况下设置内核,并存储三个不同的卷积结果,每个结果被
2
、3
或4
除法,然后选择正确的值w.r.t.角点、边框或常规像素的存在。很好,感谢您的快速回答。我理解这是如何工作的,这很有意义。但这提出了一个尖锐的问题。。。卷积在任何地方都进行,尽管实际上是在少数几个洞中进行的。这听起来效率很低。只有在洞被发现之后和发现的地方计算卷积才更明智。我认为这导致了一个更深层次的问题,这个问题植根于Numpy的实现方式,但我忍不住要在这里提及它。再次感谢!当然,对于大型图像和少量单个0
条目,这可能更快:首先找到0
条目,迭代相应的感兴趣区域(ROI),并仅适当地卷积这些ROI。但是,乍一看,我想不出一个不使用某种循环的解决方案,这是您想要避免的。