Эффективная стандартизация изображений в массиве Numpy - PullRequest
0 голосов
/ 08 мая 2018

У меня есть массив изображений в форме (N, H, W, C), где 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?

1 Ответ

0 голосов
/ 08 мая 2018

Выполните сокращения 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

Повышение производительности за счет повторного использования средних значений для вычисления стандартного отклонения в соответствии с его формулой и, следовательно, на основе 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))
...