在运动目标检测过程中,会出现这样一种情况:不同方向的两个目标在某个时刻汇合到同一地点。
在背景差检测过程中,由于区域太相近,加上形态学膨胀等处理,以至于两个距离相近的车辆位置成为一个连通区域,可能被认定为一个目标,在后续的跟踪过程中,会出现目标跟丢等情形。
这里的跟丢,是指每个目标有固定序号,在汇合后分开,先前的序号会被新的序号更新:即监测系统认定视野出现新的目标,这与现实不符。
本文提出以下方案:
- 首先判断是否是两个目标汇合情形;
- 对汇合后形成的区域拆分;
- 前两个位置分别和两个拆分后区域寻找最佳匹配。
判断是否汇合
关于是否汇合,笔者代码中有实现同一目标匹配的功能。这里暂时不系统介绍,只做单独情况处理的思路分享。
- 在新到的区域被匹配后,数据暂时不丢弃:Bool数组记录每个新检位置被匹配状态,同时记录前后位置对应序号。
- 等到后续位置再次匹配到该位置时,该区域为汇合区域可能性就很大了。
- 接下来,进一步判断区域大小,从而判断是否为待处理的汇合情况,可采取前后尺寸倍数衡量,阈值自己选择设置。
如何拆分?
关于拆分,前后位置长宽判断,可以得知在长和宽哪个方向瞬时增长,直接在那个方向等分,即可完成合并后区域的拆分。
(这里是一个比较粗糙的操作,处理两个体型相当的车辆情形比较合适;对于大小不等的目标,误差还比较大。还需完善)
拆分后匹配
拆分后的两个区域,和先前匹配到的位置,可以采用欧氏距离或者特征匹配,根据场景选择即可。
以下为判断是否区域需要拆分:
bool CPOS::NeedSeparate(cv::Rect inRect_1, cv::Rect inRect_2)
{
if ((1.6*inRect_1.width<inRect_2.width) || (1.6*inRect_1.height < inRect_2.height))
{
return true;
}
else
{
return false;
}
}
以下为拆分部分实现,就是纯粹物理分割:
void CPOS::SeparateRect(cv::Rect &inRect_1, cv::Rect &inRect_2, cv::Rect &outRect_1, cv::Rect &outRect_2)
{
if (inRect_2.width > 1.6*inRect_1.width)
{
outRect_1.x = inRect_2.x;
outRect_1.y = inRect_2.y;
outRect_1.width = 0.5*inRect_2.width;
outRect_1.height = inRect_2.height;
outRect_2.x = inRect_2.x + 0.5*inRect_2.width;
outRect_2.y = inRect_2.y;
outRect_2.width = 0.5*inRect_2.width;
outRect_2.height = inRect_2.height;
}
else if (inRect_2.height > 1.6*inRect_1.height)
{
outRect_1.x = inRect_2.x;
outRect_1.y = inRect_2.y;
outRect_1.width = inRect_2.width;
outRect_1.height = 0.5*inRect_2.height;
outRect_2.x = inRect_2.x;
outRect_2.y = inRect_2.y + 0.5*inRect_2.height;
outRect_2.width = inRect_2.width;
outRect_2.height = 0.5*inRect_2.height;
}
}
前文讲了合并,本文讲了分割,有点儿意思。