2013-03-29 6 views
11

Dato che sono nuovo su opencv, non so come usare la funzione cv.CalcEMD2 con gli array numpy.
Ho due array:Come calcolare "EMD" per 2 array numpy i.e "istogramma" usando opencv?

a=[1,2,3,4,5] 
b=[1,2,3,4] 

Come posso trasferire numpy array-CVhistogram e dal Cvhistogram al parametro funzione di signature?

Vorrei che chiunque risponda alla domanda spieghi le funzioni di opencv utilizzate tramite la soluzione fornita.

"EMD" == earth mover's distance.

Aggiornamento: -
Inoltre, sarà utile se qualcuno può dirmi come impostare il parametro di cv.CalcEMD2 cioè "signature" utilizzando numpy serie !!

Nota: -
* Per coloro che potrebbero essere interessati a questa domanda, questa risposta richiede più test.

+0

@JaimeCervantes, ho visto la tua soluzione su "EMD", ma dal momento che non capisco la struttura dei dati di 'OpenCV' così bene, ho pensato che è possibile modificare la risposta in base alla mia domanda.Thankx. –

+0

considerando questa domanda: http://stackoverflow.com/questions/5101004/python-code-for-earth-movers-distance?lq=1 –

+0

Penso di sapere come farlo, ci guarderò sopra weekend –

risposta

16

È necessario definire gli array in termini di pesi e le coordinate. Se hai due array a = [1,1,0,0,1] eb = [0,1,0,1] che rappresentano un istogramma dimensionale, allora gli array numpy dovrebbero apparire così:

a = [[1 1] 
    [1 2] 
    [0 3] 
    [0 4] 
    [1 5]] 

b = [[0 1] 
    [1 2] 
    [0 3] 
    [1 4]] 

Si noti che il numero di righe può essere diverso. Il numero di colonne dovrebbe essere le dimensioni + 1. La prima colonna contiene i pesi e la seconda colonna contiene le coordinate.

Il passaggio successivo consiste nel convertire gli array in un Mat CV_32FC1 prima di immettere l'array numpy come firma per la funzione CalcEMD2. Il codice sarà simile a questa:

from cv2 import * 
import numpy as np 

# Initialize a and b numpy arrays with coordinates and weights 
a = np.zeros((5,2)) 

for i in range(0,5): 
    a[i][1] = i+1 

a[0][0] = 1 
a[1][0] = 1 
a[2][0] = 0 
a[3][0] = 0 
a[4][0] = 1 

b = np.zeros(4,2) 

for i in range(0,4): 
    b[i][1] = i+1 

b[0][0] = 0 
b[1][0] = 1 
b[2][0] = 0 
b[3][0] = 1  

# Convert from numpy array to CV_32FC1 Mat 
a64 = cv.fromarray(a) 
a32 = cv.CreateMat(a64.rows, a64.cols, cv.CV_32FC1) 
cv.Convert(a64, a32) 

b64 = cv.fromarray(b) 
b32 = cv.CreateMat(b64.rows, b64.cols, cv.CV_32FC1) 
cv.Convert(b64, b32) 

# Calculate Earth Mover's 
print cv.CalcEMD2(a32,b32,cv.CV_DIST_L2) 

# Wait for key 
cv.WaitKey(0) 

Si noti che il terzo parametro della CalcEMD2 è la distanza euclidea CV_DIST_L2. Un'altra opzione per il terzo parametro è la distanza Manhattan CV_DIST_L1.

Vorrei anche menzionare che ho scritto il codice per calcolare la distanza del Mover terrestre di due istogrammi 2D in Python. È possibile trovare questo codice here.

+0

Il tempo è quasi finito per la taglia, stai selezionando una risposta? –

+0

Grazie, certo che lo farò, ma sto solo testando il codice. –

+0

Se 'a = [15,23,14]', qual è l'array corrispondente ** con coordinate e pesi **? –

3

CV.CalcEMD2 si aspetta array che includano anche il peso per ciascun segnale in base alla documentazione.

Vorrei suggerire che definisce gli array con un peso di 1, in questo modo:

a=array([1,1],[2,1],[3,1],[4,1],[5,1]) 
b=array([1,1],[2,1],[3,1],[4,1]) 
Problemi correlati