2016-06-15 16 views
0

Ich weiß, MATLAB und C können EMD-Fluss berechnen. Ich versuche jedoch, Python (opencv) zu verwenden, um den EMD-Fluss mithilfe der Funktion cv.CalcEMD2 zu berechnen. Gibt es eine Chance, wenn mir jemand mit cv.CalcEMD2 oder irgendeiner anderen Funktion einen EMD-Fluss geben kann?Wie berechnet man emd-Fluss mit cv.CalcEMD2 (opencv)?

Antwort

0

Hier ist ein Python-Code, der EMD und den Fluss für zwei Mischungen von Gaussian berechnet. Ich hoffe das hilft.

""" 
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()