Ну, вот реализация, которая делает то же самое, что и ваш код выше (и поворачивает изображение на соответствующий угол).
Однако в случае ваших лап я не уверен, чтоработать так же, как и для человеческой ноги.
Прежде всего, для лапы собаки «длинная» ось, определенная таким образом, расположена вдоль ширины лапы, а не по длине лапы.Это не имеет большого значения, если оно согласованно, поскольку мы можем просто повернуть на угол, рассчитанный вместо 90 - угол, вычисленный.
Однако тот факт, что лапа собаки близка к круглой, вызывает у нас больше проблем.
В принципе, это, вероятно, не будет так полезно для собак, как для людей.Вращение «длинной» оси, определяемое ковариационной матрицей изображения, сформированного из вторых центральных моментов изображения (что и делает (я думаю) ваш код выше), с меньшей вероятностью будет точным измерением ориентациилапа
Другими словами, лапа собаки близка к круглой, и они, кажется, кладут большую часть своего веса на пальцы ног, поэтому «задний» палец ноги весит меньше, чем шрифт в этом расчете.Из-за этого ось, которую мы получаем, не будет постоянно иметь отношение к положению «заднего» пальца и передних пальцев.(Надеюсь, в этом был какой-то смысл ... Я ужасный писатель ... Вот почему я отвечаю на этот вопрос, а не работаю над бумагой, над которой мне следует работать ...)
В любом случаескорость, достаточная скорость ... Вот пример:
import cPickle
import numpy as np
import matplotlib.pyplot as plt
from scipy import ndimage
def main():
measurements = cPickle.load(open('walk_sliced_data', 'r'))
plot(measurements['ser_1'].values())
plt.show()
def raw_moment(data, iord, jord):
nrows, ncols = data.shape
y, x = np.mgrid[:nrows, :ncols]
data = data * x**iord * y**jord
return data.sum()
def intertial_axis(data):
data_sum = data.sum()
m10 = raw_moment(data, 1, 0)
m01 = raw_moment(data, 0, 1)
x_bar = m10 / data_sum
y_bar = m01 / data_sum
u11 = (raw_moment(data, 1, 1) - x_bar * m01) / data_sum
u20 = (raw_moment(data, 2, 0) - x_bar * m10) / data_sum
u02 = (raw_moment(data, 0, 2) - y_bar * m01) / data_sum
angle = 0.5 * np.arctan(2 * u11 / (u20 - u02))
return x_bar, y_bar, angle
def plot(impacts):
def plot_subplot(pawprint, ax):
x_bar, y_bar, angle = intertial_axis(pawprint)
ax.imshow(pawprint)
plot_bars(x_bar, y_bar, angle, ax)
return angle
fig1 = plt.figure()
fig2 = plt.figure()
for i, impact in enumerate(impacts[:9]):
ax1 = fig1.add_subplot(3,3,i+1)
ax2 = fig2.add_subplot(3,3,i+1)
pawprint = impact.sum(axis=2)
angle = plot_subplot(pawprint, ax1)
pawprint = ndimage.rotate(pawprint, np.degrees(angle))
plot_subplot(pawprint, ax2)
fig1.suptitle('Original')
fig2.suptitle('Rotated')
def plot_bars(x_bar, y_bar, angle, ax):
def plot_bar(r, x_bar, y_bar, angle, ax, pattern):
dx = r * np.cos(angle)
dy = r * np.sin(angle)
ax.plot([x_bar - dx, x_bar, x_bar + dx],
[y_bar - dy, y_bar, y_bar + dy], pattern)
plot_bar(1, x_bar, y_bar, angle + np.radians(90), ax, 'wo-')
plot_bar(3, x_bar, y_bar, angle, ax, 'ro-')
ax.axis('image')
if __name__ == '__main__':
main()
На этих графиках центральная точка является центром тяжести изображения, а красная линия определяет «длинную» ось, а белая линия определяет«короткая» ось.
Оригинальные (не повернутые) лапы:
Повернутые лапы:
Одна вещь, на которую следует обратить внимание ... Япросто вращая изображение вокруг его центра.(Кроме того, scipy.ndimage.rotate
работает так же хорошо для массивов ND, как и для 2D. Вы также можете легко повернуть исходный 3D-массив "pawprint-over-time".)
Если вы хотите повернуть егоо точке (скажем, центроиде), и переместите эту точку в новую позицию на новом изображении, вы можете сделать это довольно легко в модуле ndimage
Сципи с помощью нескольких трюков.Я могу привести пример, если хотите.Это немного длинно для этого примера, хотя ...