返回专辑
·Johan·4 分钟阅读

光流 LK:小运动假设

calcOpticalFlowPyrLK 假设局部恒定亮度和小位移;大位移靠金字塔,曝光突变破坏亮度恒定,前后向一致性是便宜的外点剔除。

光流 LK:小运动假设

1. 大位移急转,LK 静静跟丢

急转弯 clip 上 LK track 大面积 status 等于零——不是 bug,是 brightness constancy 和 small motion 假设破了。跟踪不稳时先看曝光曲线(auto exposure 跳变),再看 pyramid levels;调 winSize 救不了曝光突变。上次底盘联调,VO track 短是因为相机 AE 在阴影出入口跳变,锁曝光后 inlier 数翻倍——前置 fix 比调 LK 参数有效。大位移急转时 LK 能静静跟丢,不是实现 bug,是假设破了。

2. 方程与 OpenCV API

亮度恒定 ,一阶展开:

局部窗口内最小二乘求 u、v。OpenCV 金字塔 LK:

python
p0 = cv2.goodFeaturesToTrack(prev, maxCorners=500, qualityLevel=0.01, minDistance=7)
p1, status, err = cv2.calcOpticalFlowPyrLK(
    prev_gray, next_gray, p0, None,
    winSize=(21, 21), maxLevel=3,
    criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 30, 0.01))

maxLevel 等于三意味约八倍最大位移覆盖;maxLevel 等于零无金字塔,大位移必 fail。winSize 奇数,典型十五到三十一;应大于等于纹理周期,纹理频率高用小窗,噪声大用大窗。err 与最小特征值相关;discard status 等于零或 err 过大点。

3. 金字塔与 aperture problem

buildOpticalFlowPyramid 先粗后精;withDerivatives 等于 True 预计算 Ix/Iy 加速;border 默认 BORDER_REFLECT_101。层数不够 → 大运动跟丢;太多 → 算力涨、小物体被 blur。LK 对 aperture problem(单条边、孔径小)无法约束法向分量——需要在 corner-like 纹理处发起 track,gradient 能量图 threshold 低的区域不跟踪。OpenCV 文档明确 LK 假设 brightness constancy。

4. 前后向一致性与稀疏/稠密取舍

forward flow 再 backward,位移差大于阈值则丢——便宜的外点剔除:

python
p0b, stb, _ = cv2.calcOpticalFlowPyrLK(next_gray, prev_gray, p1, None,
                                        winSize=(21,21), maxLevel=3)
fb_err = np.linalg.norm(p0 - p0b, axis=2).reshape(-1)
valid = (status.ravel()==1) & (stb.ravel()==1) & (fb_err < 1.0)

calcOpticalFlowFarneback 稠密光流无小运动假设但边界糊;LK sparse 适合 VO track,Farneback 适合 motion segmentation。两者都吃 exposure 稳定——auto exposure 变化时先锁曝光或做 photometric normalization。

5. 失败模式

情况表现
曝光跳变大量 status=0
大位移无金字塔跟丢
弱纹理窗口方程病态
运动模糊gradient 弱

6. 验收

track survival rate(连续 N 帧);fb error 分布;VO 里 inlier 数 vs AE 曲线。增益补偿或锁曝光是前置 fix。LK 适合小运动加亮度稳的 short track;大位移、强光照变,换特征匹配或直接法更诚实。

7. 案例:AE 跳变导致 track 大面积失败

某 VO 在阴影出入口 track 大面积 status 等于零,查曝光曲线 AE 跳变。锁曝光或增益补偿后 inlier 数翻倍——不是 winSize 问题,是 brightness constancy 破了。前置 photometric fix 比调 LK 参数有效。

8. 与 goodFeaturesToTrack 联动

LK 跟踪点质量取决于 goodFeaturesToTrack 的角点质量。qualityLevel、minDistance、maxCorners 与 LK winSize、maxLevel 一起设——在 gradient 能量低的区域不发起 track,比事后剔除外点省算力。sparse VO 链路是 detect → LK → fb consistency → pose,每步都有假设,不能跳步。

9. buildOpticalFlowPyramid 细节

withDerivatives 等于 True 预计算 Ix/Iy 加速;border 默认 BORDER_REFLECT_101。层数不够大运动跟丢;太多算力涨、小物体被 blur。OpenCV 文档明确 LK 假设 brightness constancy;auto exposure 变化时先锁曝光或 photometric normalization。

10. 验收清单

track survival rate(连续 N 帧);fb error 分布;VO inlier 数 vs AE 曲线。增益补偿或锁曝光是前置 fix。LK 适合小运动加亮度稳;大位移、强光照变换特征匹配或直接法更诚实。

11. 稀疏 vs 稠密

calcOpticalFlowFarneback 稠密光流无小运动假设但边界糊;LK sparse 适合 VO track,Farneback 适合 motion segmentation。两者都吃 exposure 稳定——选型看任务要 sparse 还是 dense、要边界还是速度。winSize 与 maxLevel 与 goodFeaturesToTrack 一起设;AE 跳变时先锁曝光,比调 LK 参数有效。前后向一致性 fb_err 阈值常用一像素;status 等于零或 err 过大点 discard。aperture problem 区域不发起 track,比事后剔除外点省算力。大位移必须 maxLevel 大于零,否则 LK 必 fail。buildOpticalFlowPyramid 的 withDerivatives 预计算 Ix/Iy 加速;border REFLECT_101 是默认。brightness constancy 破于 AE 跳变时,GMC 或锁曝光是前置;Farneback 稠密光流边界糊,LK sparse 适合 VO。track survival 连续 N 帧与 fb error 分布一起报,比只看 status 诚实。goodFeaturesToTrack 的 qualityLevel、minDistance 与 LK winSize 一起设;弱纹理区不发起 track。OpenCV 文档明确 LK 假设小运动与亮度恒定;大位移、强 AE 变,换特征匹配或直接法更诚实,别在 winSize 上死磕。calcOpticalFlowPyrLK 的 criteria 控制迭代;err 与最小特征值相关。sparse VO 链路 detect → LK → fb consistency → pose,每步假设写清,AE 跳变时前置锁曝光。

← 全部文章

johan's blog