È 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.
fonte
2013-04-08 15:33:11
@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. –
considerando questa domanda: http://stackoverflow.com/questions/5101004/python-code-for-earth-movers-distance?lq=1 –
Penso di sapere come farlo, ci guarderò sopra weekend –