有效地标准化 Numpy 数组中的图像

Chr*_*ris 6 python numpy image normalization computer-vision

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

我想按通道标准化我的图像,所以对于每个图像,我想按通道减去图像通道的平均值并除以它的标准偏差。

我在循环中执行此操作,该操作有效,但是效率非常低,并且因为它复制了我的 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)
Run Code Online (Sandbox Code Playgroud)

如何利用 numpy 的功能更有效地做到这一点?

Div*_*kar 11

沿第二个和第三个轴执行 ufunc 缩减(均值、标准差),同时保持暗淡不变,这有助于 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
Run Code Online (Sandbox Code Playgroud)

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

std = np.sqrt(((rgb_images - mean)**2).mean((1,2), keepdims=True))
Run Code Online (Sandbox Code Playgroud)

打包成一个以减少轴为参数的函数,我们将有 -

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))
Run Code Online (Sandbox Code Playgroud)