我自己找到了一个解决方案,只需要使用scipy.ndimage.generic_filter
函数。
import numpy as np
from scipy.ndimage import generic_filter
# First define the footprint of the filter you are going to use:
footprint = np.array([[False, True, False],
[True, True, True],
[False, True, False]])
# Then define the filter you want to use:
def lowpoint_kernel(a):
return 0 if a[2] < a[0] and a[2] < a[1] and a[2] < a[3] and a[2] < a[4] else 10
# Get your input here
image = ...
# Pad your image
image = np.pad(image, 1, constant_values=10)
lowpoints = generic_filter(image, lowpoint_kernel, footprint=footprint)
lowpoint_indices = lowpoints == 0
在Python中使用scipy general filter是一个好主意。
但据我所知,OpenCV没有提供这样一种方式(将自定义函数处理作为过滤器)。因此,如果您想要使用OpenCV函数来实现这个功能,可以首先应用腐蚀形态学操作(cv::erode)(使用您所需的窗口大小和二进制掩模),以获得每个像素邻域中的最小值,然后使用cv::compare方法或类似方法比较结果图像与原始图像。
要排除最小值(腐蚀)中心像素,可以将一个自定义二进制核传递给cv::erode,其中在生成的核中,中心像素为零。
总之,您应该这样做:
话虽如此,这种方法的唯一限制是在cv::erode函数中计算最小操作时必须针对非零邻居。如果这不是您想要的效果,则可以向src添加偏差,然后将其减去!
最后但并非最不重要的,如果您正在使用cpu(而不是gpu),建议使用cv :: ParallelLoopBody 一次调用即可并行实现所有过程(内存访问)。