Ask Your Question

Python : Giving a custom cost matrix in CalcEMD2?

asked 2013-03-31 09:27:07 -0500

Noam gravatar image

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 flag offensive close merge delete

1 answer

Sort by » oldest newest most voted

answered 2013-03-31 10:12:34 -0500

berak gravatar image

updated 2013-03-31 10:18:26 -0500

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

edit flag offensive delete link more


From :

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.

Noam gravatar imageNoam ( 2013-03-31 11:18:15 -0500 )edit
Login/Signup to Answer

Question Tools


Asked: 2013-03-31 09:27:07 -0500

Seen: 1,354 times

Last updated: Mar 31 '13