# Python : Giving a custom cost matrix in CalcEMD2?

I am trying to create a custom cost matrix (cyclic array indices) for earth mover's distance calculation between regular / numpy arrays :

#Example input : PointA = [0,0,1,0], PointB = [1,0,0,0]
def earthMoversDistance(pointA, pointB):
#indices = range(len(pointA))
dataA = np.array([pointA]).T
dataB = np.array([pointB]).T
def cyclicCostMatrix(length):
halfLength = int(length/2)
base = np.abs(range(-halfLength, halfLength))
base = np.roll(base, -halfLength)
return np.array([np.roll(base, i) for i in xrange(length)])
costMatrix = cyclicCostMatrix(len(pointA))
def convertArrayToCVAMat(arr):
cva64 = cv.fromarray(arr.copy())
cva32 = cv.CreateMat(cva64.rows, cva64.cols, cv.CV_32FC1)
cv.Convert(cva64, cva32)
return cva32
cvaA = convertArrayToCVAMat(dataA)
cvaB = convertArrayToCVAMat(dataB)
cvaCost = convertArrayToCVAMat(costMatrix)
emd = cv.CalcEMD2(cvaA, cvaB, cv.CV_DIST_USER, cost_matrix = cvaCost)
return emd


However, I am getting the error:

cv2.error: Only one of cost matrix or distance function should be non-NULL in case of user-defined distance


While my code may not be perfect, I am clearly not giving a distance function to the method call. Is this a bug in the python wrapper or my mistake? I am using OpenCV 2.4.2 I believe (the one that is linked to in python(x,y) ).

Any help will be much appreciated.

edit retag close merge delete

Sort by » oldest newest most voted

but you specify cv.CV_DIST_USER as flag for distance type, so it expects to be given a distance function as well (that's the complaint, it wanted both and only got the cost matrix).

you can use a cost matrix without a distance metric

you probably meant cv.CV_DIST_L1 or cv.CV_DIST_L2 or cv.CV_DIST_C here

more

distType – Used metric. CV_DIST_L1, CV_DIST_L2 , and CV_DIST_C stand for one of the standard metrics.
CV_DIST_USER means that a pre-calculated cost matrix cost is used.


From that docpage, it appears that CV_DIST_USER is the metric to use when supplying a cost matrix, as far as I can understand.

Also, the complaint seems so be that it wants either a function or a matrix but that it got both.

Official site

GitHub

Wiki

Documentation