def EarthMovers_dist(s1, s2): x = np.array(s1) y = np.array(s2) #print("x = ", x ," y = " , y) a = np.zeros((len(x), 2)) b = np.zeros((len(y), 2)) for i in range(0, len(a)): a[i][0] = x[i] a[i][1] = i + 1.0 for i in range(0, len(b)): b[i][0] = y[i] b[i][1] = i + 1.0 #print("a = ", a ," b = " , b) # 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 dis = cv.CalcEMD2( a32, b32, cv.CV_DIST_L1 ) #CV_DIST_L2 -- Euclidean Distance, CV_DIST_L1 --- Manhattan Distance return dis
def CalcEmd(histograms1, histograms2): result = 0 for i in xrange(len(histograms1)): data1 = ConvertForEmd(histograms1[i]) data2 = ConvertForEmd(histograms2[i]) distance = cv.CalcEMD2(data1, data2, cv.CV_DIST_L2) / HISTOGRAM_BIN_N result = result + distance**2 return result**0.5
def histEMD(hist1, hist2, hist1weights, hist2weights): a64 = cv.fromarray(np.hstack((hist1weights, hist1)).copy()) a32 = cv.CreateMat(a64.rows, a64.cols, cv.CV_32FC1) cv.Convert(a64, a32) b64 = cv.fromarray(np.hstack((hist2weights, hist2)).copy()) b32 = cv.CreateMat(b64.rows, b64.cols, cv.CV_32FC1) cv.Convert(b64, b32) return cv.CalcEMD2(a32, b32, cv.CV_DIST_L2)
def calcEM(hist1, hist2, h_bins, s_bins): #Define number of rows numRows = h_bins * s_bins sig1 = cv.CreateMat(numRows, 3, cv.CV_32FC1) sig2 = cv.CreateMat(numRows, 3, cv.CV_32FC1) for h in range(h_bins): for s in range(s_bins): bin_val = cv.QueryHistValue_2D(hist1, h, s) cv.Set2D(sig1, h * s_bins + s, 0, cv.Scalar(bin_val)) cv.Set2D(sig1, h * s_bins + s, 1, cv.Scalar(h)) cv.Set2D(sig1, h * s_bins + s, 2, cv.Scalar(s)) bin_val = cv.QueryHistValue_2D(hist2, h, s) cv.Set2D(sig2, h * s_bins + s, 0, cv.Scalar(bin_val)) cv.Set2D(sig2, h * s_bins + s, 1, cv.Scalar(h)) cv.Set2D(sig2, h * s_bins + s, 2, cv.Scalar(s)) #This is the important line were the OpenCV EM algorithm is called return cv.CalcEMD2(sig1, sig2, cv.CV_DIST_L2)
def calcEM(hist1, hist2, l_bins=16, u_bins=16, v_bins=16): #Define number of rows numRows = l_bins * u_bins * v_bins sig1 = cv.CreateMat(numRows, 4, cv.CV_32FC1) sig2 = cv.CreateMat(numRows, 4, cv.CV_32FC1) eq_val = 1.0 / numRows for l in range(l_bins): for u in range(u_bins): for v in range(v_bins): bin_val = cv.QueryHistValue_3D(hist1, l, u, v) cv.Set2D(sig1, l * u_bins * v_bins + u * v_bins + v, 0, cv.Scalar(bin_val)) cv.Set2D(sig1, l * u_bins * v_bins + u * v_bins + v, 1, cv.Scalar(l)) cv.Set2D(sig1, l * u_bins * v_bins + u * v_bins + v, 2, cv.Scalar(u)) cv.Set2D(sig1, l * u_bins * v_bins + u * v_bins + v, 3, cv.Scalar(v)) if hist2 == None: bin_val = eq_val else: bin_val = cv.QueryHistValue_3D(hist2, l, u, v) cv.Set2D(sig2, l * u_bins * v_bins + u * v_bins + v, 0, cv.Scalar(bin_val)) cv.Set2D(sig2, l * u_bins * v_bins + u * v_bins + v, 1, cv.Scalar(l)) cv.Set2D(sig2, l * u_bins * v_bins + u * v_bins + v, 2, cv.Scalar(u)) cv.Set2D(sig2, l * u_bins * v_bins + u * v_bins + v, 3, cv.Scalar(v)) #This is the important line were the OpenCV EM algorithm is called return (cv.CalcEMD2(sig1, sig2, cv.CV_DIST_L2), np.asarray(sig1)[:, 0], np.asarray(sig2)[:, 0])
import numpy as np import scipy.stats KL = scipy.stats.entropy(x, y) print(KL) # 编程实现 KL = 0.0 for i in range(len(px)): KL += px[i] * np.log(px[i] / py[i]) print(KL) import numpy as np import cv pp = cv.fromarray(p) qq = cv.fromarray(q) emd = cv.CalcEMD2(pp, qq, cv.CV_DIST_L2)