Question

Après avoir fait un peu de traitement sur un tableau audio ou image, il doit être normalisé dans une plage avant de pouvoir être réécrites dans un fichier. Cela peut se faire comme ceci:

# Normalize audio channels to between -1.0 and +1.0
audio[:,0] = audio[:,0]/abs(audio[:,0]).max()
audio[:,1] = audio[:,1]/abs(audio[:,1]).max()

# Normalize image to between 0 and 255
image = image/(image.max()/255.0)

Y at-il une façon moins bavard, la fonction de commodité pour le faire? matplotlib.colors.Normalize() ne semble pas être liée.

Était-ce utile?

La solution

audio /= np.max(np.abs(audio),axis=0)
image *= (255.0/image.max())

Utilisation /= et *= vous permet d'éliminer un tableau temporaire intermédiaire, économisant ainsi de la mémoire. La multiplication est moins cher que la division, donc

image *= 255.0/image.max()    # Uses 1 division and image.size multiplications

est légèrement plus rapide que

image /= image.max()/255.0    # Uses 1+image.size divisions

Puisque nous utilisons des méthodes de numpy de base ici, je pense que cela est sur une solution aussi efficace dans numpy que possible.


Opérations en place ne changent pas la DTYPE du tableau de conteneurs. Etant donné que les valeurs normalisées souhaitées sont flotteurs, les tableaux de audio et image doivent avoir le point à virgule flottante DTYPE avant que les opérations sont effectuées en place. Si elles ne sont pas déjà de DTYPE à virgule flottante, vous aurez besoin de les convertir à l'aide astype. Par exemple,

image = image.astype('float64')

Autres conseils

Si le tableau contient à la fois des données positives et négatives, je partirais avec:

import numpy as np

a = np.random.rand(3,2)

# Normalised [0,1]
b = (a - np.min(a))/np.ptp(a)

# Normalised [0,255] as integer
c = 255*(a - np.min(a))/np.ptp(a).astype(int)

# Normalised [-1,1]
d = 2.*(a - np.min(a))/np.ptp(a)-1

En outre, de mentionner, même si ce n'est pas question de l'OP, normalisation :

e = (a - np.mean(a)) / np.std(a)

Vous pouvez également rééchelonner en utilisant sklearn. Les avantages sont que vous pouvez régler normalise l'écart-type, en plus de moyenne-centrage des données, et que vous pouvez le faire sur l'un des axes, par des caractéristiques ou par des enregistrements.

from sklearn.preprocessing import scale
X = scale( X, axis=0, with_mean=True, with_std=True, copy=True )

Les arguments de mot-clé axis, with_mean, with_std sont explicites et sont présentés dans leur état par défaut. Le copy argument effectue l'opération en place si elle est définie à False. Documentation .

Vous pouvez utiliser le "i" la version (comme dans IDIV, imul ..), et il ne semble pas mal:

image /= (image.max()/255.0)

Pour l'autre cas, vous pouvez écrire une fonction de normaliser un tableau de n dimensions par colums:

def normalize_columns(arr):
    rows, cols = arr.shape
    for col in xrange(cols):
        arr[:,col] /= abs(arr[:,col]).max()

Une solution simple utilise les détartreurs offerts par la bibliothèque sklearn.preprocessing.

scaler = sk.MinMaxScaler(feature_range=(0, 250))
scaler = scaler.fit(X)
X_scaled = scaler.transform(X)
# Checking reconstruction
X_rec = scaler.inverse_transform(X_scaled)

L'erreur X_rec-X sera égal à zéro. Vous pouvez régler la feature_range pour vos besoins, ou même utiliser un scaler standart sk.StandardScaler ()

Vous essayez d'échelle min-max les valeurs de audio entre -1 et +1 et image entre 0 et 255.

Utilisation sklearn.preprocessing.minmax_scale , devrait facilement résoudre votre problème.

par exemple:.

audio_scaled = minmax_scale(audio, feature_range=(-1,1))

et

shape = image.shape
image_scaled = minmax_scale(image.ravel(), feature_range=(0,255)).reshape(shape)

Remarque : À ne pas confondre avec l'opération qui redimensionne le norme (longueur) d'un vecteur à une certaine valeur (généralement 1), qui est également communément appelé normalisation.

J'ai essayé cette , et a obtenu l'erreur

TypeError: ufunc 'true_divide' output (typecode 'd') could not be coerced to provided output parameter (typecode 'l') according to the casting rule ''same_kind''

Le tableau de numpy je tentais de normaliser était un tableau de integer. Il semble qu'ils déconseillés clichage dans les versions> 1.10, et vous devez utiliser numpy.true_divide() pour résoudre ce problème.

arr = np.array(img)
arr = np.true_divide(arr,[255.0],out=None)

img était un objet PIL.Image.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top