如何对3D NumPy数组指定区域求平均并动态配置采样区域?
动态配置图像采样区域的实现方案
问题背景
我有一个维度为(1920, 1080, 4)的3D NumPy数组,代表NoIR PiCam的视频帧,最后一维为[R, G, B, 占位字节]。目前已通过固定区域采样估算光值(代码如下),但希望动态配置采样区域——比如通过指定网格坐标(x,y)和区域大小(p,q)来抽象采样区域,想了解合适的实现方案,此前了解过scikit-image,不确定是否适配。
现有固定采样代码
average1 = np.average(np_array[240:480, 675:940, 0:3]) average1 = np.average(np_array[240:480, 675:940, 0:3]) # 笔误重复行 average2 = np.average(np_array[1440:1680, 675:945, 0:3]) average3 = np.average(np_array[840:1080, 405:675, 0:3]) average4 = np.average(np_array[240:480, 135:405, 0:3]) average5 = np.average(np_array[1440:1680, 135:405, 0:3])
实现方案
1. 纯NumPy实现(推荐,轻量灵活)
无需额外依赖,通过定义采样区域参数列表或动态生成网格区域,即可实现完全动态的采样配置:
动态配置固定区域采样
import numpy as np # 手动定义采样区域:每个元素为 (y起始, y结束, x起始, x结束) sample_regions = [ (240, 480, 675, 940), (1440, 1680, 675, 945), (840, 1080, 405, 675), (240, 480, 135, 405), (1440, 1680, 135, 405) ] # 批量计算所有区域的RGB均值 averages = [] for y_start, y_end, x_start, x_end in sample_regions: region_rgb = np_array[y_start:y_end, x_start:x_end, :3] avg = np.average(region_rgb) averages.append(avg)
按网格自动生成采样区域
如果需要按指定行数、列数和区域大小生成规则网格采样,可封装生成函数:
def generate_grid_regions(frame_shape, rows, cols, region_height, region_width): frame_h, frame_w = frame_shape[:2] # 计算网格步长,确保区域不超出帧范围 y_step = (frame_h - region_height) // (rows - 1) if rows > 1 else 0 x_step = (frame_w - region_width) // (cols - 1) if cols > 1 else 0 regions = [] for i in range(rows): y_start = i * y_step y_end = y_start + region_height for j in range(cols): x_start = j * x_step x_end = x_start + region_width regions.append((y_start, y_end, x_start, x_end)) return regions # 示例:生成3行2列、区域大小240x265的采样区域 sample_regions = generate_grid_regions(np_array.shape, 3, 2, 240, 265) # 后续均值计算同上述代码
2. scikit-image适配说明
scikit-image可以实现,但针对当前需求属于冗余依赖——它更适合复杂图像处理任务(如分割、特征提取)。如果需要用它实现规则网格采样,可使用view_as_windows生成滑动窗口:
from skimage.util import view_as_windows # 生成不重叠的规则窗口,窗口大小为(region_height, region_width, 3) region_h, region_w = 240, 265 windows = view_as_windows( np_array[:, :, :3], window_shape=(region_h, region_w, 3), step=(region_h, region_w, 3) # 步长等于窗口大小,实现不重叠采样 ) # 计算每个窗口的RGB均值,结果展平为一维列表 averages = np.mean(windows, axis=(3, 4, 5)).flatten()
这种方式仅适合规则网格采样,若需不规则区域采样,NumPy的手动配置方案更灵活。
内容的提问来源于stack exchange,提问作者Daniel Godø-Dempsey
相关产品推荐
相关产品推荐

