基于视频结构化的应用中,目标在经过跟踪算法后,会得到一个唯一标识和它对应的运动轨迹,利用这两个数据我们可以做一些后续工作:测速(交通类应用场景)、计数(交通类应用场景、安防类应用场景)以及行为检测(交通类应用场景、安防类应用场景)。我会写三篇文章依次介绍这三个主题。
(1)目标跟踪之速度计算
(2)目标跟踪之计数
(3)目标跟踪之行为检测
后面会陆续添加链接。
本篇文章以交通类应用场景为例,介绍车辆断面计数方法。
人工计数方式
设想一个场景,你蹲在地下通道旁边,要统计穿过这条通道最近5分钟的人流量,你实际的做法是什么?目光是停留在一个人身上,从TA进入通道直到离开吗?当然不是,因为这样的话你根本没有那么多双眼睛。正常人会在通道中某个位置想象出来一条虚拟分界线,目光紧盯这条线附近区域即可,有人跨线计数就加一。他们是不会关注这条直线两边稍远区域的目标,因为那里有什么、有多少目标都不会影响最终的计数结果。
如上图,对于A区域和B区域范围内的目标,观察者是不需要考虑的,只有经过黄色虚拟计数线的目标才会纳入计数范畴。在A和B区域出现的目标停留、调头等都不影响最终的计数结果。
自动计数原理
自动计数原理其实跟人工计数一致,计数算法应该同样假设出一条虚拟的分界线,目标穿过这条虚拟的分界线时,总计数加一。前面提到过,目标经过跟踪算法处理后,会得到一个唯一目标标识和对应的运动轨迹坐标点集合,通过这两个数据可以很快判断某个目标是否穿越某条直线。2D平面中判断一个点(X,Y)在一条直线(X1, Y1)(X2, Y2)左侧还是右侧的算法很简单,下面是对应代码:
1 // check if point at one side of line 2 bool LeftOfLine(Point p, Point p1, Point p2) 3 { 4 if (p1.X == p2.X) 5 { 6 return p.X < p1.X; 7 } 8 9 if (p1.Y == p2.Y) 10 { 11 return p.Y < p1.Y; 12 } 13 14 if (p2.X < p1.X) 15 { 16 Point tmp = p2; 17 p2 = p1; 18 p1 = tmp; 19 } 20 21 int ret = (p2.Y - p.Y) * (p2.X - p1.X) - (p2.Y - p1.Y) * (p2.X - p.X); 22 return ret < 0; 23 }