所以我有一个具有伪环形运动的对象(编辑:具有非恒定周期)。我用 30 fps 的相机拍摄它,每 3 帧提取一次它的位置 X 和 Y。而且,这个圆周运动的中心是移动的。
参赛资料:
- 框架,列表
- X 和 Y , 2 个列表
对于 Frame[i],对象的位置是 X[i] 和 Y[i]。
此外,我的数据有“间隙”,有时我可以从第 600 帧到第 690 帧,因为在我的视频中没有正确检测到对象。数据已经用一阶低通滤波器过滤(在按段插值之后)。
我的问题是,我找不到一个好的算法来计算旋转次数,而没有太多的可变性。
当前算法使用 X 和 Y 的伪周期性:
for length = 200, 400, 600, 800, 1000 and 1200 :
I cut my data (X and Y) in segments of size : length.
for each segments cutted :
Mean_X = Mean value of X on the segment
Mean_Y = Mean value of Y on the segment
If I get above Mean_X, X_counter += 1, and then I skip the following points until I get under Mean_X.
Same with Y_counter.
I sum the counted number of rotation on each segments for the current length to get the number of rotation on the complete duration.
In 2 list, ResX and ResY, I store the counted number of rotation for every length. To resX[i] correspond the length i.
For instance resX[2] give the number counted for length : 600.
But the results on X and Y are different, and have an high variability depending of the length chosen.
So how to choose the real number of rotation on the duration ?
Calculation of the difference of counted number between X and Y for every length.
Then I choose the average of counted X and Y, where there is the smaller difference.
在 Python 中:
# Découpage en segment de 200 à 1200 de longueur avec un pas de 200
Segments = range(200, 1400, 200)
ResX, ResY = [], []
for k in range(len(Segments)):
if Segments[k] < len(X):
X_calc, Y_calc = [], []
length = len(X) // Segments[k]
last = len(X) % Segments[k]
for j in range(length):
X_calc.append(X[j:j + Segments[k]])
Y_calc.append(Y[j:j + Segments[k]])
if last > Segments[k] //2:
X_calc.append(X[len(X) - last:])
Y_calc.append(Y[len(Y) - last:])
else:
X_calc[len(X_calc) - 1] = X_calc[len(X_calc) - 1] + X[len(X) - last:]
Y_calc[len(Y_calc) - 1] = Y_calc[len(Y_calc) - 1] + Y[len(Y) - last:]
# Initialisation of the counter
Kx = 0
Ky = 0
for j in range(len(X_calc)):
Counter = 0
b = 0
Moyenne = np.mean(X_calc[j])
while b < len(X_calc[j]):
if X_calc[j][b] <= Moyenne + 10:
b += 1
continue
else:
Counter += 1
while X_calc[j][b] >= Moyenne + 10:
b += 1
try:
X_calc[j][b]
except:
break
Kx += Counter
Counter = 0
b = 0
Moyenne = np.mean(Y_calc[j])
while b < len(Y_calc[j]):
if Y_calc[j][b] <= Moyenne + 10:
b += 1
continue
else:
Counter += 1
while Y_calc[j][b] >= Moyenne + 10:
b += 1
try:
Y_calc[j][b]
except:
break
Ky += Counter
ResX.append(Kx)
ResY.append(Ky)
# Maintenant on détermine le nombre de tour en comparant les résultats locaux en X et en Y
Diff = []
for j in range(len(ResX)):
Diff.append(abs(ResX[j] - ResY[j]))
ID = Diff.index(min(Diff))
Res_F = int((ResX[ID] + ResY[ID]) /2)
该当前解决方案具有很高的可变性,具体取决于:
- 长度
- “计数高于值”:如果我取平均值(X)或平均值(X)+ 10,我会得到完全不同的结果。
你知道如何减少这种可变性吗?或者关于计算旋转的算法的想法?或者在计数之前结合 X 和 Y 的方法?
由于 (t = 0, X = 1, Y = 0) 的旋转可以用 X = cos(t) 和 Y = sin(t) 来描述,我认为有一种方法可以将 X 和 Y 相加或相乘为了分析 X 和 Y 的线性组合。