[英]Python low-pass filter on list of Time/Position
首先讓我解釋一下我的目標和問題。 我有一個物體在 bocal(准確地說是老鼠)內成圈運動 ,我需要知道它在一分鍾內旋轉了多少圈 。 這個運動不是一個完美的循環,並且可能是混亂的 。 它可以停止幾秒鍾,然后再次開始移動。
但是我知道的是,我每分鍾旋轉3到20次 => 低頻(0.05 Hz到0.33 Hz之間 )。
我正在30分鍾內用30 fps的相機拍攝該對象。 使用Python和OpenCV,我設法提取(X,Y)坐標。 由於30 fps對於我要尋找的頻率來說有點高,因此我選擇了15幀來獲得2 Hz的采樣頻率 。
第一個問題是,有時我會遺漏一點,因為OpenCV無法找到對象。 這是我無法解決的問題,因為使用HSV彩色蒙版跟蹤的點有時是隱藏的。
實際上,我要過濾的數據是:
例如,我有這樣的列表:
現在, 我的問題是 :即使我在過濾和編碼方面有一些基礎知識,我也不知道該怎么做以及使用哪個庫。 我讀過scipy應該具有所有必需的功能,但是我不知道要使用哪個,以及如何使用。
我不確定,但是我認為我應該做這樣的事情:
您能告訴我我是否正確,並為編碼部分指明正確的方向嗎?
謝謝您的幫助,
馬蒂厄
在深入研究傅立葉變換之前,您可以僅應用一階或二階低通濾波器。 您可以先對數據進行線性插值,以使頻率恆定為2Hz
。 然后,您可以將一階低通濾波器應用於數據點。
y_k = a * x_k + (1-a) * y_km1, a in [0,1]
x_k是您的觀察值,y_k是您的濾波后的估計值。
然后,如果第一個原型產生了一些有用的結果,則您也許可以使用一些物理模型來獲得更好的估計量。 卡爾曼濾波器可以更好地利用您的基本物理現實。 但是為此,您首先需要了解如何為物理現實建模的想法。
https://en.wikipedia.org/wiki/Kalman_filter
在這里,您也許還可以找到有關跟蹤計算機視覺運動的更接近的示例: http : //www.diss.fu-berlin.de/docs/servlets/MCRFileNodeServlet/FUDOCS_derivate_000000000473/2005_12.pdf
所以這是我按照您告訴我的方法計算出的代碼:我創建了2個函數:
目前,我還沒有嘗試過更改a的值以找到正確的值,但是絕對可以給我帶來很好的結果。
def Interpolation(Frame, X, Y, Frequence = 2):
"""Fonction réalisant l'interpolation cubique des points manquants si possible, avec le découpage en segment si nécessaire."""
# Détermination de la séparation entre les Frames pour la fréquence d'échantillonage choisie
FPS = 30
DT = FPS / Frequence
# Initialisation
i = 0
# Détermination du début de l'interpolation
try:
while Frame[i+2] - Frame[i] != 2 * DT:
i += 1
continue
except:
print ("Erreur : Il est impossible de commencer l'interpolation.")
# Suppresion des points antérieurs
Frame = Frame[i:]
X = X[i:]
Y = Y[i:]
k = 0
Frame_id = list()
# Recherche des segments
for i in range(len(Frame) - 1):
if Frame[i+1] - Frame[i] > 6 * DT:
Frame_id.append((k, i))
k = i + 1
# Ajout du dernier segment
if k != len(Frame) - 1:
Frame_id.append((k, len(Frame)-1))
# Suppresion des segments de moins de 3 points
for k in reversed(range(len(Frame_id))):
i = Frame_id[k][0]
j = Frame_id[k][1]
if j - i < 2:
del Frame_id[k]
continue
Abs_inter, X_inter, Y_inter = [], [], []
for index in Frame_id:
i = index[0]
j = index[1]
# Génération des abscisses sur chaque segment, ainsi que des fonctions interpolés
Abscisse = np.arange(Frame[i], Frame[j] + DT, DT)
fX = interp1d(Frame[i:j+1], X[i:j+1], kind = 'cubic')
fY = interp1d(Frame[i:j+1], Y[i:j+1], kind = 'cubic')
# Génération des nouvelles coordonnées sur le segment
Xnew = fX(Abscisse)
Ynew = fY(Abscisse)
Abs_inter += Abscisse.tolist()
X_inter += Xnew.tolist()
Y_inter += Ynew.tolist()
# Création des listes résultats finaux
Frame_final, X_final, Y_final = [], [], []
Time = 0
while Time <= Abs_inter[len(Abs_inter)-1]:
if Time in Frame:
Frame_final.append(Time)
X_final.append(X[Frame.index(Time)])
Y_final.append(Y[Frame.index(Time)])
Time += DT
continue
elif Time in Abs_inter:
Frame_final.append(Time)
X_final.append(X_inter[Abs_inter.index(Time)])
Y_final.append(Y_inter[Abs_inter.index(Time)])
Time += DT
continue
else:
Time += DT
return (Frame_final, X_final, Y_final)
def Filtrage2(Frame, X, Y, DT = 15, a = 0.1):
"""Fonction réalisant un filtrage passe-bas d'ordre 1 du signal."""
# Initialisation
X_temp, Y_temp = [], []
X_filter, Y_filter = [], []
i = 1
X_temp.append(X[0])
Y_temp.append(Y[0])
# Filtrage par morceau
while i < len(Frame):
while Frame[i] - Frame[i-1] == DT:
Xnew = a * X[i-1] + (1 - a) * X_temp[len(X_temp)-1]
Ynew = a * Y[i-1] + (1 - a) * Y_temp[len(Y_temp)-1]
X_temp.append(Xnew)
Y_temp.append(Ynew)
if i < len(Frame)-1:
i += 1
else:
break
X_filter += X_temp
Y_filter += Y_temp
X_temp, Y_temp = [], []
X_temp.append(X[i])
Y_temp.append(Y[i])
i += 1
return (X_filter, Y_filter)
我也嘗試過在scipy庫中使用Butterworth過濾器,但無法正常工作。 這是我無法解決的代碼:
def Filtrage(Frame, X, Y, DT = 15, fc = 0.5, frequence = 2, order = 5):
"""Fonction réalisant un filtrage passe-bas du signal."""
# Détermination du filtre
nyq = 0.5 * frequence
normal_cutoff = fc / nyq
b, a = butter(order, normal_cutoff, btype = 'low', analog = False)
# Filtrage par morceau
X_temp, Y_temp = [], []
X_filter, Y_filter = [], []
# Initialisation
X_temp.append(X[0])
Y_temp.append(Y[0])
i = 1
while i < len(Frame):
while Frame[i] - Frame[i-1] == DT:
X_temp.append(X[i])
Y_temp.append(Y[i])
if i < len(Frame)-1:
i += 1
else:
break
X_filter += lfilter(b, a, X_temp).tolist()
Y_filter += lfilter(b, a, Y_temp).tolist()
X_temp, Y_temp = [], []
X_temp.append(X[i])
Y_temp.append(Y[i])
i += 1
return (X_filter, Y_filter)
如果您對如何使Butterworth發揮作用有任何想法,我將很高興聽到。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.