有效地标准化Numpy阵列中的图像

问题描述 投票:2回答:1

我有一个形状(N, H, W, C)的numpy数组图像,其中N是图像的数量,H图像高度,W图像宽度和C RGB通道。

我希望通过频道标准化我的图像,因此对于每个图像,我想通过通道方式减去图像通道的平均值并除以其标准偏差。

我在一个循环中完成了这个工作,但它效率非常低,因为它复制了我的RAM太满了。

def standardize(img):
    mean = np.mean(img)
    std = np.std(img)
    img = (img - mean) / std
    return img

for img in rgb_images:
    r_channel = standardize(img[:,:,0])
    g_channel = standardize(img[:,:,1])
    b_channel = standardize(img[:,:,2])
    normalized_image = np.stack([r_channel, g_channel, b_channel], axis=-1)
    standardized_images.append(normalized_image)
standardized_images = np.array(standardized_images)

如何更有效地利用numpy的功能呢?

python image numpy computer-vision normalization
1个回答
4
投票

沿着第二和第三轴执行ufunc减少(mean,std),同时保持dims完整,这有助于broadcasting以后的分割步骤 -

mean = np.mean(rgb_images, axis=(1,2), keepdims=True)
std = np.std(rgb_images, axis=(1,2), keepdims=True)
standardized_images_out = (rgb_images - mean) / std

通过重新使用平均值来计算标准差来进一步提高性能,根据其公式,因此受到this solution的启发,如此 -

std = np.sqrt(((rgb_images - mean)**2).mean((1,2), keepdims=True))

将轴作为参数打包成一个函数,我们可以 -

from __future__ import division

def normalize_meanstd(a, axis=None): 
    # axis param denotes axes along which mean & std reductions are to be performed
    mean = np.mean(a, axis=axis, keepdims=True)
    std = np.sqrt(((a - mean)**2).mean(axis=axis, keepdims=True))
    return (a - mean) / std

standardized_images = normalize_meanstd(rgb_images, axis=(1,2))
© www.soinside.com 2019 - 2024. All rights reserved.