用光流判断设备转没转,比死盯检测框稳多了
问题
我做的那个程序,要盯着一根缓慢旋转的金属管(往水里喷水的那种),判断它到底在转还是停了。转 + 喷 = 正常,转没了或者喷没了就报警。
一开始我想得很简单:既然用模型把这根管子框出来了,那就看框的中心位置相对水池中心有没有变。有位移就是转了,没位移就是停了。目标检测管”有没有”,位置变化管”动没动”,听起来天衣无缝。
现象
实际一跑就露怯。那根管子转得特别慢,一圈要好几十秒,单帧之间框中心挪的距离也就几个像素,和检测本身抖动的误差差不多大。结果就是:明明在转,程序一会儿判”在转”、一会儿判”停了”,跳来跳去;有时候真停了,框因为水面反光轻微晃,反而被误判成”在转”。
更麻烦的是,管子转的时候,框不是整体平移,是绕着水池中心转,中心位移和”转不转”的关系本来就不是线性的。靠框中心位移去推转动,信号太弱、噪声太强。
执行效果:
缓慢旋转时:框中心单帧位移 ≈ 3~5px,检测抖动 ≈ 2~4px
现象:转动判定反复横跳(转/停/转/停),误报漏报都高
怎么解决
我换了思路:不去盯”框在哪”,而是看框里面”像素往哪个方向流”。管子在转,它表面的纹理、水花在 ROI 里会朝一个大致一致的方向运动——这就是光流方向一致性。
具体做法:在管子所在的 ROI 里算光流,看这些运动矢量是不是大体指向同一个方向(一致性高 = 在转),而不是看框中心挪了没挪。缓慢旋转时,虽然整体位移小,但局部纹理一直在朝一个方向滑,方向一致性照样能累积出来确认转动。
模型还是照常用——它负责把管子从画面里框出来、定 ROI,但”转没转”这个动态判断,交给传统视觉方法(光流)做,各管一摊。
执行效果:
缓慢旋转时:ROI 内光流方向一致性稳定 > 阈值,几秒内确认"在转" ✅
停止时:方向一致性掉下来,持续几秒判"停" ✅
不再随检测框抖动乱跳
结论
目标检测是好东西,但它天生擅长”认东西在不在、在哪”,不擅长”东西在怎么动”。凡是涉及旋转、移动、动作这类动态判断,别硬用检测框的位置变化去推,信号弱还招噪声。
现在的分工我觉着顺:模型负责”框出目标、圈定区域”,光流/帧差这类传统方法负责”区域里发生了什么运动”。两者搭着用,比单靠模型稳得多。这次之后,但凡碰到”判断一个东西动没动”的需求,我都会先想一句——这事儿是该问检测框,还是该问像素流。