You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在numpy数组中高效识别邻域HSV值相近的像素?

没有完全和你期望的proximity_mask同名的开箱即用函数,但可以通过Python科学计算生态的成熟工具,几行代码封装出完全符合你要求的实现,同时比手动写多次roll的方案可维护性更高、性能相当甚至更好。

方案1:用scipy现有工具快速实现

你可以通过scipy.ndimage.generic_filter快速实现需求,支持任意形状的邻域核,写法非常灵活:

import numpy as np
from scipy.ndimage import generic_filter

def proximity_mask(src, kernel, proximity):
    def check_neighbours(window):
        # window是按kernel拉平的邻域像素,中心为第len(window)//2位
        center_val = window[len(window)//2]
        # 仅检测kernel为1的位置的邻域
        neighbour_vals = window[kernel.flatten() == 1]
        # 所有邻域和中心的差值都小于阈值才返回True
        return np.all(np.abs(neighbour_vals - center_val) < proximity)
    
    # 边界像素直接设为False,避免误判
    return generic_filter(src, check_neighbours, footprint=kernel, mode='constant', cval=np.inf)

调用方式完全和你期望的一致:

mask = proximity_mask(src=hues, kernel=np.ones((3,3)), proximity=3)

方案2:纯numpy高性能实现(推荐)

如果对执行效率要求很高,可以用numpy 1.20+ 新增的sliding_window_view实现完全向量化的邻域检测,没有Python层循环开销,性能和手写多轮roll操作持平:

import numpy as np
from numpy.lib.stride_tricks import sliding_window_view

def proximity_mask(src, kernel, proximity):
    h, w = src.shape
    kernel_h, kernel_w = kernel.shape
    # 对源矩阵做padding,边界填充无穷大避免和中心值误判为接近
    pad_h, pad_w = kernel_h // 2, kernel_w // 2
    padded_src = np.pad(src, ((pad_h, pad_h), (pad_w, pad_w)), mode='constant', constant_values=np.inf)
    # 生成滑动窗口视图,无额外内存开销
    windows = sliding_window_view(padded_src, (kernel_h, kernel_w))
    center_vals = src[..., None, None]
    # 仅kernel为1的位置参与比较
    neighbour_mask = kernel == 1
    mask = np.all((np.abs(windows - center_vals) < proximity) | ~neighbour_mask, axis=(-1, -2))
    return mask

另外你原有实现中用np.roll会存在边界误差:roll会把图像另一侧的像素循环移动到边界位置作为邻域,边界像素的判断结果是错误的,上述两个方案都通过padding处理了边界问题,结果更准确。

内容的提问来源于stack exchange,提问作者P i

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 22:15:03