You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 04:53:30