好吧,这是一个与上面的代码执行相同操作的实现(并将图像旋转相关角度)。
然而,就你的爪子而言,我不确定它是否能像人脚一样有效。
首先,对于狗的爪子,以这种方式定义的“长”轴是沿着爪子的宽度而不是爪子的长度。只要保持一致,这并不重要,因为我们可以简单地旋转计算出的角度,而不是 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()
在这些图中,中心点是图像的质心,红线定义“长”轴,而白线定义“短”轴。
Original (Unrotated) Paws:
Rotated Paws:
这里需要注意的一件事......我只是围绕其中心旋转图像。 (还,scipy.ndimage.rotate
对于 N 维数组和 2D 数组都适用。您可以轻松旋转原始 3D“随时间变化的爪印”阵列。)
如果您确实想围绕一个点(例如质心)旋转它,并将该点移动到新图像上的新位置,您可以在 scipy 中相当轻松地完成ndimage
通过一些技巧来模块。如果你愿意的话我可以举个例子。不过这个例子有点长......