cv2使用卡爾曼濾波(Kalman Filter)捕捉滑鼠運動
阿新 • • 發佈:2018-10-31
本文主要介紹在cv2中使用Kalman濾波捕捉滑鼠運動。
cv2.KalmanFilter(dynamParams=None,#狀態的維度
measureParams=None, #測量的維度
controlParams=None,#控制的維度
type=None)#矩陣的型別
下面是示例程式碼:
import cv2 import numpy as np # 建立一個大小800*800的空幀 frame = np.zeros((800, 800, 3), np.uint8) # 初始化測量座標和滑鼠運動預測的陣列 last_measurement = current_measurement = np.array((2, 1), np.float32) last_predicition = current_prediction = np.zeros((2, 1), np.float32) ''' mousemove()函式在這裡的作用就是傳遞X,Y的座標值,便於對軌跡進行卡爾曼濾波 ''' def mousemove(event, x, y, s, p): # 定義全域性變數 global frame, current_measurement, measurements, last_measurement, current_prediction, last_prediction # 初始化 last_measurement = current_measurement last_prediction = current_prediction # 傳遞當前測量座標值 current_measurement = np.array([[np.float32(x)], [np.float32(y)]]) # 用來修正卡爾曼濾波的預測結果 kalman.correct(current_measurement) # 呼叫kalman這個類的predict方法得到狀態的預測值矩陣,用來估算目標位置 current_prediction = kalman.predict() # 上一次測量值 lmx, lmy = last_measurement[0], last_measurement[1] # 當前測量值 cmx, cmy = current_measurement[0], current_measurement[1] # 上一次預測值 lpx, lpy = last_prediction[0], last_prediction[1] # 當前預測值 cpx, cpy = current_prediction[0], current_prediction[1] # 繪製測量值軌跡(綠色) cv2.line(frame, (lmx, lmy), (cmx, cmy), (0, 100, 0)) # 繪製預測值軌跡(紅色) cv2.line(frame, (lpx, lpy), (cpx, cpy), (0, 0, 200)) cv2.namedWindow("kalman_tracker") # 呼叫函式處理滑鼠事件,具體事件必須由回撥函式的第一個引數來處理,該引數確定觸發事件的型別(點選和移動) ''' void setMousecallback(const string& winname, MouseCallback onMouse, void* userdata=0) winname:視窗的名字 onMouse:滑鼠響應函式,回撥函式。指定窗口裡每次滑鼠時間發生的時候,被呼叫的函式指標。 這個函式的原型應該為void on_Mouse(int event, int x, int y, int flags, void* param); userdate:傳給回撥函式的引數 void on_Mouse(int event, int x, int y, int flags, void* param); event是 CV_EVENT_*變數之一 x和y是滑鼠指標在影象座標系的座標(不是視窗座標系) flags是CV_EVENT_FLAG的組合, param是使用者定義的傳遞到setMouseCallback函式呼叫的引數。 常用的event: CV_EVENT_MOUSEMOVE CV_EVENT_LBUTTONDOWN CV_EVENT_RBUTTONDOWN CV_EVENT_LBUTTONUP CV_EVENT_RBUTTONUP 和標誌位flags有關的: CV_EVENT_FLAG_LBUTTON ''' cv2.setMouseCallback("kalman_tracker", mousemove) ''' Kalman這個類需要初始化下面變數: 轉移矩陣,測量矩陣,控制向量(沒有的話,就是0), 過程噪聲協方差矩陣,測量噪聲協方差矩陣, 後驗錯誤協方差矩陣,前一狀態校正後的值,當前觀察值。 在此cv2.KalmanFilter(4,2)表示轉移矩陣維度為4,測量矩陣維度為2 卡爾曼濾波模型假設k時刻的真實狀態是從(k − 1)時刻的狀態演化而來,符合下式: X(k) = F(k) * X(k-1) + B(k)*U(k) + W(k) 其中 F(k) 是作用在xk−1上的狀態變換模型(/矩陣/向量)。 B(k) 是作用在控制器向量uk上的輸入-控制模型。 W(k) 是過程噪聲,並假定其符合均值為零,協方差矩陣為Qk的多元正態分佈。 ''' kalman = cv2.KalmanFilter(4, 2) # 設定測量矩陣 kalman.measurementMatrix = np.array([[1, 0, 0, 0], [0, 1, 0, 0]], np.float32) # 設定轉移矩陣 kalman.transitionMatrix = np.array([[1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0], [0, 0, 0, 1]], np.float32) # 設定過程噪聲協方差矩陣 kalman.processNoiseCov = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]], np.float32) * 0.03 while True: cv2.imshow("kalman_tracker", frame) if (cv2.waitKey(30) & 0xff) == 27: break cv2.destroyAllWindows()
執行結果: