光流分析是計算機視覺中的重要技術,用于檢測視頻序列中物體的運動模式。本文將介紹如何使用OpenCV和Python實現一個實時的光流分析系統,該系統能夠檢測運動、生成熱力圖并提供詳細的統計分析。
技術概述
本系統基于Farneback稠密光流算法,能夠:
-
實時計算視頻幀之間的運動向量
-
生成運動熱力圖可視化
-
提供多種統計分析(均值、中位數、眾數等)
-
顯示歷史數據趨勢圖表
核心代碼解析
初始化設置
class DenseOpticalFlow:def __init__(self):self.init_parameters()self.prev_time = Noneself.fps = 30# 歷史統計數據self.max_history_length = 100self.displacement_history = deque(maxlen=self.max_history_length)self.mean_history = deque(maxlen=self.max_history_length)self.median_history = deque(maxlen=self.max_history_length)self.mode_history = deque(maxlen=self.max_history_length)self.speed_history = deque(maxlen=self.max_history_length)
使用deque
數據結構來存儲歷史數據,自動維護固定長度的歷史記錄。
光流計算
def do(self, frame, device="cpu"):current_time = cv2.getTickCount() / cv2.getTickFrequency()gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 計算光流flow = cv2.calcOpticalFlowFarneback(self.prev_gray, gray_frame, None,self.flow_params["pyr_scale"], self.flow_params["levels"],self.flow_params["winsize"], self.flow_params["iterations"],self.flow_params["poly_n"], self.flow_params["poly_sigma"],self.flow_params["flags"])
使用OpenCV的calcOpticalFlowFarneback
函數計算稠密光流,該算法能夠為每個像素點生成運動向量。
數據處理與可視化
# 計算運動幅值
magnitude, _ = cv2.cartToPolar(flow[...,0], flow[...,1])# 排除0值,只分析實際運動區域
nonzero_magnitude = magnitude[magnitude > 0]# 生成熱力圖
magnitude_norm = cv2.normalize(magnitude, None, 0, 255, cv2.NORM_MINMAX)
heatmap = cv2.applyColorMap(np.uint8(magnitude_norm), cv2.COLORMAP_INFERNO)
通過極坐標轉換獲取運動幅值,并使用INFERNO色彩映射生成熱力圖,紅色表示高強度運動,藍色表示低強度運動。
統計分析
# 計算統計量
if len(nonzero_magnitude) > 0:mean_val = float(np.mean(nonzero_magnitude))median_val = float(np.median(nonzero_magnitude))mode_val = float(stats.mode(nonzero_magnitude, keepdims=True)[0][0])
else:mean_val = median_val = mode_val = 0.0# 更新歷史數據
self.mean_history.append(mean_val)
self.median_history.append(median_val)
self.mode_history.append(mode_val)
系統計算三種主要統計量:
-
均值:運動幅值的平均值
-
中位數:運動幅值的中位數,對異常值不敏感
-
眾數:最常見的運動幅值
可視化界面
def add_statistics_chart(self, side_by_side, magnitude):# 創建matplotlib圖表fig = plt.figure(figsize=(width/100, chart_height/100), dpi=100)gs = fig.add_gridspec(1,2, width_ratios=[1,1], wspace=0.3)# 左圖:當前幀位移分布直方圖ax1 = fig.add_subplot(gs[0])if len(magnitude) > 0:ax1.hist(magnitude.flatten(), bins=30, color="green", alpha=0.7)# 右圖:歷史統計趨勢線ax2 = fig.add_subplot(gs[1])x_vals = np.arange(len(self.mean_history))if len(x_vals) > 0:ax2.plot(x_vals, list(self.mean_history), label="Mean", color="blue")ax2.plot(x_vals, list(self.median_history), label="Median", color="orange")ax2.plot(x_vals, list(self.mode_history), label="Mode", color="green")
可視化界面分為兩部分:
-
左側直方圖:顯示當前幀的運動幅值分布
-
右側折線圖:顯示最近100幀的統計趨勢
應用場景
1. 運動檢測與監控
-
檢測監控視頻中的異常運動
-
統計人流量和運動模式
-
識別運動方向和強度
2. 體育分析
-
分析運動員的運動軌跡
-
計算運動速度和加速度
-
評估運動表現
3. 交通監控
-
檢測車輛運動
-
分析交通流量
-
識別交通違規行為
4. 科學研究
-
動物行為研究
-
流體動力學分析
-
微觀粒子運動跟蹤
結論
本文介紹的光流分析系統提供了一個完整的運動檢測解決方案,結合了實時處理、統計分析和可視化功能。通過OpenCV和Python的強大組合,開發者可以輕松實現各種運動相關的計算機視覺應用。
該系統具有良好的可擴展性,可以根據具體需求添加更多功能,如物體跟蹤、行為識別和高級統計分析。無論是學術研究還是工業應用,這都是一個強大的基礎框架。
對 PiscTrace or PiscCode感興趣?更多精彩內容請移步官網看看~🔗?PiscTrace