使用Horn and Schunck算法目标追踪遇cv2无calcOpticalFlowHS属性错误
解决OpenCV中无
calcOpticalFlowHS的问题并实现Horn-Schunck光流目标追踪 问题原因
OpenCV的Python官方库中没有内置cv2.calcOpticalFlowHS函数,这是触发AttributeError的直接原因。Horn-Schunck光流算法需要手动实现核心逻辑,以下是修正后的完整方案。
修正后的完整代码
import cv2 import numpy as np def horn_schunck_optical_flow(prev_gray, curr_gray, alpha=0.5, num_iterations=30, window_size=32): # 初始化光流场 u = np.zeros_like(prev_gray, dtype=np.float32) v = np.zeros_like(prev_gray, dtype=np.float32) # 计算图像梯度与时间差 Ix = cv2.Sobel(prev_gray, cv2.CV_32F, 1, 0, ksize=3) Iy = cv2.Sobel(prev_gray, cv2.CV_32F, 0, 1, ksize=3) It = curr_gray.astype(np.float32) - prev_gray.astype(np.float32) # 创建均值滤波核,保证光流平滑性 kernel = np.ones((window_size, window_size), dtype=np.float32) / (window_size**2) # 迭代求解光流场 for _ in range(num_iterations): u_avg = cv2.filter2D(u, -1, kernel) v_avg = cv2.filter2D(v, -1, kernel) numerator = Ix * u_avg + Iy * v_avg + It denominator = alpha**2 + Ix**2 + Iy**2 # 更新光流分量 u = u_avg - Ix * numerator / denominator v = v_avg - Iy * numerator / denominator return np.stack((u, v), axis=-1) # 读取视频文件 cap = cv2.VideoCapture('vid.mp4') # 读取第一帧并转灰度 ret, frame1 = cap.read() if not ret: print("视频读取失败") exit() frame1_gray = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY) # 逐帧处理视频 while True: ret, frame2 = cap.read() if not ret: break frame2_gray = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY) # 调用自定义Horn-Schunck光流计算函数 flow = horn_schunck_optical_flow(frame1_gray, frame2_gray, alpha=0.5, num_iterations=3, window_size=32) # 计算光流幅值与角度 mag, ang = cv2.cartToPolar(flow[...,0], flow[...,1]) # 阈值筛选运动区域 threshold = 2.5 # 适配Horn-Schunck算法输出的小幅值光流 mask = np.zeros_like(frame1_gray) mask[mag > threshold] = 255 # 形态学操作去除噪声 kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel) # 显示结果 cv2.imshow('Object detection', mask) # 更新前一帧 frame1_gray = frame2_gray.copy() # 按q键退出 if cv2.waitKey(25) & 0xFF == ord('q'): break # 释放资源 cap.release() cv2.destroyAllWindows()
关键修改说明
- 新增
horn_schunck_optical_flow函数,基于算法原理实现光流计算,核心包括图像梯度求解、光流场迭代更新与平滑处理 - 调整光流幅值阈值至2.5,Horn-Schunck算法输出的光流幅值通常较小,原25的阈值会过滤所有有效运动
- 增加视频读取失败的判断逻辑,提升代码健壮性
内容的提问来源于stack exchange,提问作者Sumit Bose
相关产品推荐
相关产品推荐

