Подтвердить что ты не робот

Как вычислить "EMD" для 2 массивов numpy i.e "гистограмма" с использованием opencv?

Поскольку я новичок в opencv, я не знаю, как использовать функцию cv.CalcEMD2 с массивами numpy.
У меня два массива:

a=[1,2,3,4,5]  
b=[1,2,3,4]

Как передать numpy array в CVhistogram и от CVhistogram к параметру функции signature?

Я хотел бы, чтобы любой, кто ответил на вопрос, объяснил любые используемые функции opencv через предоставленное решение.

"EMD" == расстояние от земли.

Обновление: - Страница Кроме того, будет полезно, если кто-нибудь скажет мне, как установить параметр cv.CalcEMD2 i.e "signature" с помощью массива numpy!!

Примечание: - Страница  * Для тех, кто может быть заинтересован в этом вопросе, этот ответ требует дополнительного тестирования.

4b9b3361

Ответ 1

Вы должны определить свои массивы с точки зрения веса и координат. Если у вас есть два массива a = [1,1,0,0,1] и b = [0,1,0,1], которые представляют собой одномерные гистограммы, то массивы numpy должны выглядеть так:

a = [[1 1]
     [1 2]
     [0 3]
     [0 4]
     [1 5]]

b = [[0 1]
     [1 2]
     [0 3]
     [1 4]]

Обратите внимание, что количество строк может быть различным. Число столбцов должно быть размером + 1. Первый столбец содержит веса, а второй столбец содержит координаты.

Следующим шагом будет преобразование ваших массивов в CV_32FC1 Mat, прежде чем вы вводите массив numpy в качестве сигнатуры функции CalcEMD2. Код будет выглядеть так:

from cv2 import *
import numpy as np

# Initialize a and b numpy arrays with coordinates and weights
a = np.zeros((5,2))

for i in range(0,5):
    a[i][1] = i+1

a[0][0] = 1
a[1][0] = 1
a[2][0] = 0
a[3][0] = 0
a[4][0] = 1

b = np.zeros(4,2)

for i in range(0,4):
    b[i][1] = i+1

b[0][0] = 0
b[1][0] = 1
b[2][0] = 0
b[3][0] = 1    

# 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
print cv.CalcEMD2(a32,b32,cv.CV_DIST_L2)

# Wait for key
cv.WaitKey(0)

Обратите внимание, что третьим параметром CalcEMD2 является евклидово расстояние CV_DIST_L2. Другим вариантом для третьего параметра является расстояние Manhattan CV_DIST_L1.

Я также хотел бы упомянуть, что я написал код для вычисления расстояния Земли от двух двумерных гистограмм в Python. Вы можете найти этот код здесь.

Ответ 2

CV.CalcEMD2 ожидает массивы, которые также включают вес для каждого сигнала в соответствии с документацией.

Я бы предложил определить ваши массивы с весом 1, например:

a=array([1,1],[2,1],[3,1],[4,1],[5,1])
b=array([1,1],[2,1],[3,1],[4,1])