我的目标是实现一个中值滤波器,这是一个函数,它用周围像素的中值替换(大部分)2d阵列中的每个像素。它可以用于图像去噪
我的实现从原始矩阵中提取子矩阵,其中包含像素本身及其邻域。这个提取目前是使用for循环完成的,正如您所想象的,for循环占用了大约95%的执行时间
以下是我当前的实现:
def median_blur(img, fsize=3):
img_intermediate = np.zeros((img.shape[0] + 2, img.shape[1] + 2), np.uint8) # First intermediate img, used for padding original image
img_intermediate[1:img.shape[0]+1, 1:img.shape[1]+1] = img
img_result = np.empty((*img.shape, fsize, fsize), np.uint8) # Will contain result, first receives kernel-submatrices
# Extract submatrices from image
for i in range(img.shape[0]):
for j in range(img.shape[1]):
img_result[i, j] = img_intermediate[i:i+fsize, j:j+fsize]
img_result = img_result.reshape(*img.shape, fsize**2) # Reshape Result-Matrix
img_result = np.median(img_result, axis=2) # Calculate median in one go
return img_result.astype('uint8')
如何使用矢量化操作提取这些子矩阵?
作为奖励,如果有计算机视觉经验的人正在读这篇文章:除了将中值滤波器应用于中间零填充矩阵之外,还有更好的实现中值滤波器的方法吗
多谢各位
这是一个矢量化的解决方案。但是,通过注意图像阵列的内存顺序,您可以想出一个更快的解决方案:
首先使用
pad
函数填充,然后使用as_strided
获得子矩阵,最后将median
应用于步幅更新:在评论中使用@Divakar建议的
view_as_windows
:view_as_windows
还提供类似于跨步的子矩阵示例图像和输出:
相关问题 更多 >
编程相关推荐