Domanda

Dopo aver eseguito alcune elaborazioni su un array audio o di immagini, è necessario normalizzarlo entro un intervallo prima di poterlo riscrivere in un file.Questo può essere fatto in questo modo:

# 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)

Esiste un modo meno dettagliato e comodo per farlo? matplotlib.colors.Normalize() non sembra essere correlato.

È stato utile?

Soluzione

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

Utilizzando /= e *= permette di eliminare un array temporaneo intermedio, risparmiando così un po 'di memoria. Moltiplicazione è meno costoso di divisione, quindi

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

è marginalmente più veloce di

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

Dal momento che stiamo usando metodi NumPy base qui, penso che si tratta di una soluzione più efficiente in NumPy come può essere.


In luogo operazioni non modificano il dtype dell'array contenitore. Poiché i valori normalizzati desiderati sono galleggianti, le matrici audio e image necessario avere a virgola mobile punto dtype prima di eseguire le operazioni in-place. Se non sono già di virgola mobile DTYPE, è necessario convertirli utilizzando astype. Ad esempio,

image = image.astype('float64')

Altri suggerimenti

Se l'array contiene sia i dati positivi e negativi, mi piacerebbe andare con:

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

Inoltre, vale la pena menzionare anche se non è questione di OP, standardizzazione :

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

È inoltre possibile ridimensionare utilizzando sklearn. I vantaggi sono che è possibile regolare a normalizzare la deviazione standard, oltre a significare-centratura i dati, e che si può fare questo in asse o, per le caratteristiche, o record.

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

L'argomento chiave axis, with_mean, with_std sono auto esplicative, e sono mostrati nel loro stato di default. Il copy argomento esegue l'operazione sul posto se è impostato a False. Documentazione qui .

È possibile utilizzare la "i" (come in idiv, IMUL ..) versione, e non guardare niente male:

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

Per l'altro caso è possibile scrivere una funzione per normalizzare una matrice n-dimensionale colonne:

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

Una soluzione semplice sta usando i ablatori offerti dalla biblioteca 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'errore X_rec-X sarà pari a zero. È possibile regolare il feature_range per le vostre esigenze, o anche utilizzare uno sk.StandardScaler standart scaler ()

Stai cercando di ridimensionare min-max i valori di audio tra -1 e +1 e image compreso tra 0 e 255.

Utilizzando sklearn.preprocessing.minmax_scale, dovrebbe risolvere facilmente il tuo problema.

per esempio.:

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

E

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

Nota:Da non confondere con l'operazione che ridimensiona il norma (lunghezza) di un vettore a un determinato valore (solitamente 1), comunemente indicato anche come normalizzazione.

Ho provato seguendo questo , e ottenuto l'errore

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

La matrice numpy stavo cercando di normalizzare era una matrice integer. Sembra che deprecati casting di tipo nelle versioni> 1.10, e si deve utilizzare numpy.true_divide() per risolvere questo.

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

img era un oggetto PIL.Image.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top