ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Python+OpenCV光流估计实战:从原理到参数调优与实验报告

Python+OpenCV光流估计实战:从原理到参数调优与实验报告 简介面向计算机视觉初学者与开发者这份资料围绕光流估计的核心原理与工程实现展开覆盖Lucas-Kanade、Farneback等经典算法可应用于运动目标跟踪、视频稳定、3D重建等场景解决视频中像素级运动信息提取问题。压缩包共含3个文件以avi示例视频、py算法脚本和docx实验报告为三大主体前者提供测试素材中间是可运行代码后者为完整实验说明便于对照学习整包仅8.24MB轻量易下载。目前已有809人学习下载。脚本基于OpenCV实现完整光流计算流程包括视频帧灰度化与归一化预处理、金字塔级别与搜索窗口等参数配置、光流计算及箭头可视化可直接复现并观察运动轨迹。实验报告则从算法数学模型、关键代码段说明、结果叠加展示、平均欧氏距离误差等性能评估到应用场景探讨逐一展开并记录了排错思路与项目反思可作为计算机视觉课程设计或大作业的参考模板。对于希望快速掌握光流估计并动手实践的研究者这份资源提供了可复现的完整链路能显著降低入门门槛。1. 光流估计是什么视频处理里那个算“谁在动”的算法光流估计是计算机视觉里最容易被低估的模块给两帧连续视频算出画面里每个像素从上一帧动了多少、往哪个方向移。运动目标检测、视频稳像、目标跟踪都建立在它之上很多 Python 视频项目就是从调通一个光流函数开始的。这篇笔记基于 OpenCV 的 Python 接口把光流原理、稠密与稀疏实现、参数调优和实验报告写法串一遍。资源里带可直接运行的代码、测试素材和报告模板刚装好 Python 的人能跟步骤跑通熟手能直接拿去调参。适合做视频目标跟踪的学生、想练手计算机视觉的 Python 开发者以及需要交光流实验报告的课程选手。2. 光流原理与算法选型从亮度恒定方程到 LK 与 Farneback 的取舍2.1 亮度恒定方程光流问题的出发点光流算法不是看“像素长得像不像”而是默认一个核心假设同一个物体点在两帧之间亮度不变。写成公式是 I(x, y, t) ≈ I(xdx, ydy, tdt)对右边做一阶泰勒展开并忽略高阶项就得到I_x * u I_y * v I_t 0I_x、I_y 是图像在 x、y 方向的梯度I_t 是时间方向上的梯度在离散实现里就是当前帧减上一帧的差分。u、v 是我们要求的光流分量。这个方程叫亮度恒定方程1981 年 Horn-Schunck 的论文之后几乎所有经典光流算法都从它出发。问题在于一个方程有两个未知数解不唯一。这就是光流领域常说的孔径问题——你透过一个小窗口看一条均匀的斜边只能感知到垂直于边缘方向的分量沿边缘方向的移动完全看不出来。真实世界满屏都是这种退化情况。所以整个光流领域的研究本质上都是在回答同一个问题怎么补上第二个约束。Lucas-Kanade 用“邻域内所有像素运动一致”来补Horn-Schunck 用“全场运动平滑”来补Farneback 用局部多项式系数拟合来补。这里还要注意亮度假定要求两帧之间的位移足够小因为泰勒展开丢掉了二次及以上项运动越快近似误差越大。这也是图像金字塔存在的意义先把大位移放到缩小后的图像上粗略估计再回原尺度精修。所以“小位移”只约束方程本身不是整个算法的全局假设。这个推导顺序建议在实验报告里原样写一遍再补一句“本实验采用恒定光照视频亮度恒定假设成立”先声明条件再展示结果评审能挑的毛病就少一个。2.2 稀疏与稠密LK、HS、Farneback 的适用边界OpenCV 里最常用的三个光流接口是 calcOpticalFlowPyrLK、calcOpticalFlowFarneback 和 calcOpticalFlowHS。选型的核心分叉是稀疏还是稠密。LK 是稀疏光流的代表。它的做法是先做角点检测Shi-Tomasi 或 Harris挑出纹理明显的点然后假设角点邻域内所有像素共享同一个运动向量。把窗口内 N 个像素代入同一个方程就得到 N 个方程两个未知数的超定方程组最小二乘解就是 (u, v)。当窗口内只有一个方向的梯度比如直线边缘时最小二乘的矩阵接近奇异解会非常不稳——这就是为什么角点才是可靠跟踪点边缘不行。LK 的计算量小、速度快适合特征点跟踪和视觉里程计坏处是只有角点有光流白墙、天空这种弱纹理区域选不出点整片没有输出。Farneback 是稠密光流的默认选择对每个像素都输出 (u, v)。它的核心思想是用多项式基函数对局部图像做近似拟合——可以粗略理解为给每个小窗口拟合一个二次曲面——然后比较两帧同名窗口的多项式系数差异反推位移。OpenCV 的实现带图像金字塔能覆盖中等程度的位移。计算量明显大于 LK但对运动场完整性要求高的场景比如视频稳像、运动分割、帧插值它是工程上的默认答案。Horn-Schunck 把求解变成一个全局能量最小化问题数据项要求满足亮度恒定平滑项惩罚相邻像素间的光流差。理论上一套很漂亮的变分框架实际工程却用得很少——全局平滑会把运动物体和背景的边缘一起糊掉迭代收敛也慢。我在实战里的习惯是只跟踪少数特征点用 LK要完整的运动场用 FarnebackHS 放进课程实验与 LK 做对比充当实验报告“算法对比”章节的素材。2.3 三种算法的一页选型表算法输出密度计算速度抗大位移典型场景LK (PyrLK)稀疏仅特征点快靠金字塔较强角点跟踪、视觉里程计HS稠密慢弱教学实验、算法对比Farneback稠密中金字塔加多项式较强视频稳像、运动检测、帧插值选型还有个容易忽略的前提PyrLK 和 Farneback 都是多尺度实现内部自带金字塔。真实视频里物体位移经常超过 30 像素720p 下一个人走两步就可能超过单尺度光流在这种输入上几乎必崩。这也是为什么实验报告对比单尺度与多尺度、LK 与 Farneback 时结论容易写成“Farneback 更好”——不一定是算法本身更强而是多尺度策略救了它。写报告时把这个点写透比罗列一堆参数更有说服力。提示选型不要只看“哪个结果好看”。稀疏光流适合下游只依赖少数可靠点的任务稠密光流适合需要完整运动场的任务。先定下游需求再选算法顺序反了容易被结果牵着走。3. Python 实现光流估计OpenCV 读帧、计算与可视化全流程3.1 环境准备装对库是第一步这份资源里的代码基于 Python 3.8 和 OpenCV 4.x依赖只有 opencv-python 和 numpy 两个包pip install opencv-python numpy如果你用 Anaconda 做实验也可以走 conda 源conda install -c conda-forge opencv这里有个新手常踩的坑opencv-python 和 opencv-contrib-python 不要同时装。contrib 版只多了 SIFT、KAZE 等特征模块光流接口两个版本都有实验场景装基础版足够。装完用一段验证代码确认环境import cv2 import numpy as np print(cv2.__version__) # 应该是 4.x如果 import 直接报错百分之八十是机器上残留了多个 OpenCV 版本。常见做法是新建一个干净的虚拟环境再装一遍Windows 上尤其容易翻车因为系统里常同时存在用户级和系统级 Pythonpip 装到的库和 Jupyter 用的解释器很可能不是同一个。python -m venv flowenv 建环境激活后再 pip install能省下大半天的排查时间。3.2 稠密光流calcOpticalFlowFarneback 与 HSV 可视化稠密光流输出的是每个像素的 (u, v) 位移直接看数值不直观。通用做法是把这个二维向量编码成颜色方向对应色相 H速度大小对应亮度 V。下面是完整的读视频、算光流、可视化、按键退出的流程import cv2 import numpy as np cap cv2.VideoCapture(input.mp4) ret, prev cap.read() if not ret: raise IOError(无法读取视频请检查路径) prev_gray cv2.cvtColor(prev, cv2.COLOR_BGR2GRAY) # HSV 可视化容器饱和度为固定值H/V 两通道循环更新 hsv np.zeros_like(prev) hsv[..., 1] 255 while cap.isOpened(): ret, frame cap.read() if not ret: break gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) flow cv2.calcOpticalFlowFarneback( prev_gray, gray, None, pyr_scale0.5, levels3, winsize15, iterations3, poly_n5, poly_sigma1.2, flags0, ) # 第 0 通道是 ux 方向位移第 1 通道是 vy 方向位移 mag, ang cv2.cartToPolar(flow[..., 0], flow[..., 1]) hsv[..., 0] ang * 180 / np.pi / 2 hsv[..., 2] cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX) bgr cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) combo np.hstack([frame, bgr]) cv2.imshow(dense flow | left: raw, right: flow, combo) if cv2.waitKey(30) 0xFF ord(q): break prev_gray gray.copy() cap.release() cv2.destroyAllWindows()代码逻辑拆开讲calcOpticalFlowFarneback 的返回值是与原图同尺寸的双通道 float32 数组[..., 0]是 x 方向位移 u[..., 1]是 y 方向位移 vcartToPolar 把直角坐标转成极坐标得到幅值 mag 和方向角 ang。接下来把角度映射到色相ang 是弧度乘 180/pi 转角度再除以 2压到 0 到 180 的 HSV 色相范围把幅值归一化到 0 到 255 赋给亮度通道。这里一个关键习惯hsv 容器在循环外只初始化一次循环里只更新 H 和 V 通道S 保持 255。每次都整体重建的话颜色会越来越浑浊还白白多一次内存分配。Farneback 的参数含义值得逐一说清实验报告里经常会被问到。pyr_scale 是金字塔缩放系数0.5 表示每层图像缩小为上一层的二分之一levels 是金字塔层数3 层大约覆盖十几到三十像素的位移winsize 是多项式拟合的窗口大小15 是常见平衡值画面纹理细碎时调到 21 往往更稳iterations 是每层迭代次数3 到 5 之间差异很小poly_n 是拟合多项式的邻域大小通常取 5 或 7越大对噪声越钝但边缘越糊poly_sigma 是高斯标准差与 poly_n 配套大约是 poly_n 的 0.25 到 0.4 倍。这几个参数在第 4 章会单独讲怎么调。3.3 稀疏光流Pyramid LK 的特征点追踪稀疏光流的思路是“先选点、再跟踪”用 goodFeaturesToTrack 检测 Shi-Tomasi 角点再交给 calcOpticalFlowPyrLK 逐帧匹配import cv2 import numpy as np cap cv2.VideoCapture(input.mp4) ret, prev cap.read() prev_gray cv2.cvtColor(prev, cv2.COLOR_BGR2GRAY) # Shi-Tomasi 角点检测最多 200 个、质量阈值 0.3、最小间距 7 像素 prev_pts cv2.goodFeaturesToTrack( prev_gray, maxCorners200, qualityLevel0.3, minDistance7, blockSize7, ) lk_params { winSize: (15, 15), maxLevel: 2, criteria: (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03), } while cap.isOpened(): ret, frame cap.read() if not ret: break gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) next_pts, status, err cv2.calcOpticalFlowPyrLK( prev_gray, gray, prev_pts, None, **lk_params ) # status 1 表示该点匹配成功失败点的坐标是 NaN good_new next_pts[status 1] good_old prev_pts[status 1] for new, old in zip(good_new, good_old): x1, y1 old.ravel() x2, y2 new.ravel() cv2.arrowedLine(frame, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2) cv2.imshow(sparse flow | LK corner tracking, frame) if cv2.waitKey(30) 0xFF ord(q): break prev_gray gray.copy() # 跟踪点会随遮挡和漂移不断减少必须定期重新补充 if len(good_new) 100: new_pts cv2.goodFeaturesToTrack(gray, 200, 0.3, 7) if new_pts is not None: prev_pts np.vstack((good_new.reshape(-1, 1, 2), new_pts)) else: prev_pts good_new.reshape(-1, 1, 2) else: prev_pts good_new.reshape(-1, 1, 2) cap.release() cv2.destroyAllWindows()这段代码有两个最容易漏的点。第一calcOpticalFlowPyrLK 返回的 status 数组标记每个点是否匹配成功必须用 status 1 过滤否则会把失败点的 NaN 坐标直接画到画面上表现为箭头偶尔跳去右下角第二特征点会不断流失——物体被遮挡、纹理被运动模糊、形变过大都会让匹配失败——纯跟踪不补充的话一两百帧后画面上就剩零星几个点。我一般会在跟踪点数低于阈值时触发重新检测把新角点拼进 prev_pts。这个“维护点集”的动作是稀疏光流工程化里最重要的一步比调任何参数都管用。winSize 决定相邻帧匹配窗口的大小跟踪快速小物体要调大maxLevel 是金字塔层数2 到 3 层常见criteria 里的 10 是迭代次数上限0.03 是精度阈值控制 LK 求解的收敛条件通常不用改。3.4 把结果写成视频VideoWriter 的使用与编码坑实验报告通常要求交结果视频OpenCV 写视频用 VideoWriterfourcc cv2.VideoWriter_fourcc(*mp4v) writer cv2.VideoWriter( flow_result.mp4, fourcc, fps30, size(combo.shape[1], combo.shape[0]), ) # 循环内每次 imshow 之后 writer.write(combo) # 循环结束后 writer.release()我一般是先读完第一帧算出 combo再用它的宽高去初始化 writer避免最后写出来一个 0KB 的空文件。mp4v 编码在部分播放器里会花屏Windows 上遇到打不开就换 MJPG 编码并把后缀改成 .avifourcc cv2.VideoWriter_fourcc(*MJPG) writer cv2.VideoWriter(flow_result.avi, fourcc, 30, size)fps 要和输入视频保持一致否则整段结果会被快放或慢放这是实验验收时最扎眼的扣分项。另外注意部分编码器要求宽高为偶数如果输入视频是奇数分辨率写视频会直接报错用size(w // 2 * 2, h // 2 * 2)强制取偶是常见做法。4. 光流参数调优与工程化金字塔、预处理和后处理三板斧4.1 参数优先级先调金字塔再动窗口Farneback 的七个参数灵敏度天差地别瞎调是最浪费时间的方式。我反复试过多轮之后形成的习惯是先确定 levels 和 pyr_scale 这两个金字塔参数再动 winsize最后才碰 poly_n 和 poly_sigma。参数典型值调大效果调小效果什么时候动levels3覆盖更大位移边缘更平滑响应更快适合小位移视频里快速运动明显winsize15光流更平滑、抗噪细节更丰富、更容易碎纹理细或噪点多poly_n5抗噪更强、边缘糊边缘更锐、易受噪声干扰低照度视频poly_sigma1.2平滑更强更敏感通常随 poly_n 联动金字塔参数决定“算法能感知多大位移”。视频相邻两帧里目标移动超过 20 像素很常见此时 levels1 的单层实现几乎必然给出错误光流。有个快速验证方法把光流幅值图的平均值打印出来如果某帧均值突然跳到异常大的值多半是金字塔层数不够而不是真的运动变大。winsize 是“局部一致性”的量化窗口越大“区域内运动一致”的假设越难成立运动物体边缘容易互相污染窗口太小单像素噪声直接进多项式拟合结果就碎。我一般会在 11 到 21 之间试两三个值选视觉上边缘最干净的那个而不是硬套某个固定数字。调参这事在光流这里确实有点玄学但核心原则只有一条金字塔管“够不够远”窗口管“够不够稳”先远后稳。4.2 预处理比调参更早该做的事很多光流效果不好不是参数的问题而是输入就不合格。下面三招按性价比排序几乎每类视频都能受益。第一降采样。1080p 视频直接跑 Farneback只能到个位数帧率而且高分辨率下微小抖动会被算法当成有效运动放大。常见做法是把视频长边缩到 640 到 960 再算光流视觉损失极小速度提升数倍scale 640 / frame.shape[1] resized cv2.resize(frame, (640, int(frame.shape[0] * scale)))第二高斯模糊。视频压缩噪声和传感器噪点会让多项式拟合抖得厉害算光流前先做一次轻模糊gray cv2.GaussianBlur(cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY), (5, 5), 0)核大小 3 或 5 即可太大反而把纹理细节磨掉。第三低照度视频做对比度增强。亮度恒定假设在暗光下很容易失效因为暗部梯度噪声占比太高。我常用 CLAHEclahe cv2.createCLAHE(clipLimit2.0, tileGridSize(8, 8)) gray clahe.apply(gray)CLAHE 是自适应直方图均衡不会像全局均衡那样把整幅图提亮到过曝对夜间监控视频的效果比较明显。需要提一句对比度增强改动的是像素强度理论上会偏离原始亮度恒定假设所以实验报告里要写明预处理步骤并把“预处理前 vs 预处理后”并列展示这反而成了加分项。4.3 用脚本批量扫参数告别盲调手动改参数再播放视频效率太低。我一般写一个小脚本把候选参数组合跑一遍记录每组的处理耗时和运动幅值然后一次性对比import time import numpy as np import cv2 def bench(prev_gray, gray, params): t0 time.time() flow cv2.calcOpticalFlowFarneback(prev_gray, gray, None, **params) dt time.time() - t0 mag np.linalg.norm(flow, axis2) return dt, mag.mean(), flow candidates [ {pyr_scale: 0.5, levels: 3, winsize: 15, iterations: 3, poly_n: 5, poly_sigma: 1.2, flags: 0}, {pyr_scale: 0.5, levels: 4, winsize: 21, iterations: 3, poly_n: 7, poly_sigma: 1.5, flags: 0}, {pyr_scale: 0.5, levels: 2, winsize: 11, iterations: 5, poly_n: 5, poly_sigma: 1.1, flags: 0}, ] for i, p in enumerate(candidates): dt, avg_mag, flow bench(prev_gray, gray, p) print(fparams[{i}] time{dt:.3f}s avg_mag{avg_mag:.2f})这个脚本的价值在于把“感觉哪个参数更好”变成“数据说明哪个参数更快、运动响应更合理”。没有真值数据集时平均幅值是一个可以用但必须谨慎的代理指标幅值整体偏大不一定代表准也可能代表把噪声当成了运动。所以批量扫参只用于缩小候选范围最终判断还要回到可视化人工看物体边缘是否跟得住、背景是否干净。注意扫参脚本里 prev_gray 和 gray 必须是同一段视频同一帧的前后帧且每组参数都用相同输入否则对比没有意义。先固定输入再动参数这是做光流实验最基本的原则。5. 光流实战避坑五条让我翻过车的血泪经验5.1 光流图几乎全黑只有零星亮点现象Farneback 跑完右半边光流可视化基本是黑的只有少数边缘附近有颜色。原因多数情况是帧率与运动速度不匹配。固定机位拍摄的 30fps 视频里背景像素本来就几乎不动光流幅值趋近于 0归一化之后亮度当然低。另一部分是输入图像对比度太低比如阴天户外梯度接近 0亮度恒定方程解出来全是近零位移。解决先用一段有明显平移的测试视频验证算法本身是否正常确认光流图有预期颜色再换回正式数据。如果场景运动确实太小把 normalize 的分母改小或改用固定范围归一化比如cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX, -1, None, 1.0)之后乘一个放大系数让小幅值也有可见亮度如果是对比度低按 4.2 节做一遍 CLAHE 再重跑。5.2 稀疏光流跑到一半画面上箭头全消失现象LK 跟踪起初有两三百个绿色箭头几十帧后数量骤减最后只剩几个甚至为零。原因跟踪本身在持续丢点——物体出画、遮挡、旋转都会让 LK 配准失败更隐蔽的原因是代码里没有“补充点”的逻辑丢一个少一个少了就再也回不来。解决在每帧迭代末尾强制检查有效点数量低于阈值就重跑一次 goodFeaturesToTrack 并合并新旧点集这段逻辑在第 3.3 节代码里已经给出工程上属于必写逻辑而不是可选优化。另外确认 qualityLevel 别设太高0.3 以下比较稳妥minDistance 别大于目标尺寸否则小目标上根本选不出点。5.3 1080p 视频 Farneback 只有个位数帧率现象winsize21、levels4 在 1920x1080 上每帧耗时 200 到 500 毫秒实时性完全没法用。原因稠密光流是逐像素计算计算量随分辨率近似线性增长金字塔层数和 winsize 反过来又增加每层的多项式拟合开销。高分辨率加高参数帧率必然崩。解决除非下游明确要求全分辨率光流否则先把长边缩到 640 或 960。我做过对比720p 降到 640 宽视觉结果几乎无损单帧耗时降 4 到 8 倍。缩放后精度仍然不够时优先增加金字塔层数而不是放大 winsize因为大窗口对高分辨率下的纹理细节破坏更严重。最后检查代码层面的小优化灰度图只在必要时转换、避免每帧重复分配大数组能把剩余开销再压掉一截。5.4 画面亮度突变光流瞬间乱成一团现象场景里有人开了灯或者摄像头自动曝光调整时光流图整幅变成高亮杂色运动方向随机。原因亮度恒定方程的前提是 I_t 只由运动产生。开灯这种光照突变会让 I_t 暴涨算法把亮度变化误判成位移于是静止场景也出了光流。这是所有避坑里最伤的一次——我当时拿夜间监控做运动检测一晚上全在报到摄像头自动切换红外模式时的假报警。解决工程上常见做法是逐帧计算全局亮度均值若两帧之间变化超过阈值例如 20/255说明发生了非运动性亮度突变跳过这一帧不更新光流直接复用上一帧结果。阈值按场景光线稳定性在 5% 到 15% 之间调。做完这一步还要把跳帧事件打日志方便事后核对为什么中间会有一段“画面静止”也方便在报告里向评审解释这一段为什么没有有效输出。5.5 用公开数据集评估EPE 大得离谱现象在 Middlebury 或 KITTI 数据集上跑 Farneback平均端点误差EPE算出来几十个像素看起来算法完全不可用。原因两种典型情况。一是拿自己的光流输出和真值直接比但没对齐尺寸和坐标范围二是忽略了失效区域遮挡、速度不连续区域把真值为 0 的无效像素也计入误差分母数值被抬高或稀释。解决评估之前先明确对齐三步把光流结果 resize 到与真值一致确认单位换算.flo 文件里单位是像素部分数据集用归一化坐标两者不能混用只统计有效像素。规范化做法是使用数据集自带的 mask 文件过滤遮挡区域再算 EPE 和 AAE。把无效像素也算进去是光流评估里最典型的“数字好看但结论全错”的坑。6. 光流实验报告EPE 指标计算与结果呈现技巧6.1 用 Python 算 EPE 与 AAE 指标EPE平均端点误差和 AAE平均角度误差是光流评估的标准指标。EPE 是预测光流与真值向量差的二范数平均AAE 是两向量夹角的平均值。读取标准 .flo 格式并计算的脚本import numpy as np def read_flo(path): with open(path, rb) as f: tag np.frombuffer(f.read(4), dtypenp.float32) if tag[0] ! 202021.25: raise ValueError(不是标准 .flo 文件) w, h np.frombuffer(f.read(8), dtypenp.int32) data np.frombuffer(f.read(), dtypenp.float32) return data.reshape((h, w, 2)) gt read_flo(gt.flo) pred read_flo(pred.flo) epe np.linalg.norm(pred - gt, axis2) valid np.isfinite(epe) print(EPE:, epe[valid].mean()) dot (pred * gt).sum(axis2) norm np.linalg.norm(pred, axis2) * np.linalg.norm(gt, axis2) angle np.arccos(np.clip(dot / np.maximum(norm, 1e-8), -1.0, 1.0)) print(AAE:, np.rad2deg(angle[valid]).mean()).flo 的布局是 4 字节浮点标签、int32 宽高、再按行存储光流数据reshape 顺序必须是 (h, w, 2)写反了整张光流图会左右转置。arccos 之前要把比值 clip 到 [-1, 1]否则浮点误差会产生 NaN。6.2 实验报告结构按验收顺序组织一份能拿高分的光流实验报告按下面顺序组织评审能一路顺下来章节内容常见扣分点原理亮度恒定方程、三种算法约束差异只贴公式不解释约束来源实验数据集、预处理、参数表只有一组参数没有消融对比结果光流可视化、EPE/AAE 表没有色环图例对比尺寸不一致分析算法对比、失败案例只说好话不说边界图表有个很实用的技巧光流图必须配色环不同算法对比必须同一帧、同一色环范围否则视觉上无法公平比较。另外主动放一张失败案例低纹理区域的空洞、大位移处的撕裂并解释成因比假装完美更能拿分。6.3 让结论站得住写结论时把“Farneback 更好”改成有前提的陈述“在本实验的分辨率、运动幅度和光照条件下Farneback 的 EPE 比 LK 低约 40%”。条件、指标、数字齐全结论才可验证。从那以后我每次做光流实验都强制走一遍固定流程先固定输入帧和分辨率再扫金字塔参数再做预处理消融最后用同一份真值算 EPE 和 AAE 并留档。这套流程帮我避开了至少三次“参数没对齐就下结论”的事故。希望帮到你。本文还有配套的精品资源点击获取
返回列表