2016-06-15 2 views
0

私はMATLABを知っており、CはEMDフローを計算できます。しかし、関数cv.CalcEMD2を使用してEMDフローを計算するためにpython(opencv)を使用しようとしています。誰かが私にcv.CalcEMD2やEMDフローを取得するための関数を使って例を与えることができますか?cv.CalcEMD2(opencv)を使用してemdフローを計算する方法は?

答えて

0

ここでは、ガウス分布の2つの混合物のEMDと流れを計算するいくつかのPythonコードを示します。私はそれが助けて欲しい

""" 
Compute earth mover's distance (EMD) to compare two mixtures of Gaussians 

Requires: numpy, cv2, csb 
""" 
import numpy as np, cv2 
from csb.numeric import log_sum_exp 

class GMM(object): 
    """ 
    1d mixture of Gaussians 
    """ 
    def __init__(self, K): 
     """ 
     K: number of components 
     """ 
     self.mu = np.zeros(K) 
     self.sigma = np.ones(K) 
     self.w = np.ones(K) 
     self.w/= self.w.sum() 

    @property 
    def K(self): 
     return len(self.mu) 

    def log_prob(self, x): 
     logp = - 0.5 * np.subtract.outer(x, self.mu)**2/self.sigma**2. \ 
      - 0.5 * np.log(2*np.pi*self.sigma**2) + np.log(self.w) 

     return log_sum_exp(logp.T,0) 

    def __call__(self, x, normed=True): 

     logp = self.log_prob(x) 
     if np.iterable(x) and normed: 
      logp -= log_sum_exp(logp) 

     return np.exp(logp) 

    def randomize(self, mu_range=(-10, 10.), sigma_range=(0.1, 5.)): 

     self.mu[...] = np.random.uniform(*mu_range, size=self.K) 
     self.sigma[...] = np.random.uniform(*sigma_range, size=self.K) 
     self.w[...] = np.random.random(self.K) 
     self.w /= self.w.sum() 

def make_signature(x, p): 

    P = np.transpose([p,x]) 
    P64 = cv2.cv.fromarray(np.array(P.tolist())) 
    P32 = cv2.cv.CreateMat(P64.rows, P64.cols, cv2.cv.CV_32FC1) 
    cv2.cv.Convert(P64, P32) 

    return P32 

def calc_emd(q, p, x): 

    Q = make_signature(x, q) 
    P = make_signature(x, p) 

    flow = cv2.cv.CreateMat(len(q), len(p), cv2.cv.CV_32F) 
    cv2.cv.Set(flow, 0.) 

    return cv2.cv.CalcEMD2(P, Q, cv2.cv.CV_DIST_L2, flow=flow), np.asarray(flow[:,:]) 

if __name__ == '__main__': 

    x = np.linspace(-10., 10., 100) 

    ## create two mixtures of Gaussians with 3 and 5 components 

    f = GMM(3) 
    g = GMM(5) 

    f.randomize() 
    g.randomize() 

    ## evaluate mixtures on 1d grid 

    q = f(x) 
    p = g(x) 

    ## compute EMD and flow 

    emd, F = calc_emd(q, p, x) 

    ## check marginals 

    print np.fabs(F.sum(0) - q).max(), np.fabs(F.sum(1)-p).max() 
関連する問題