SORT 多目标跟踪算法+opencv模板匹配算法实战——多个小球跟踪,以及演示视频

实现结果

先把最终结果放上来,个人感觉效果还是非常棒的。

rgb

sort+模板匹配实现多目标跟踪

灰度图像假彩色

假彩色反映的是模板匹配的匹配程度,越红代表相似度越高。

sort+模板匹配实现多目标跟踪

二值化,提取坐标

对模板匹配后的结果,进行二值化等操作,获取小球中心点坐标。

sort+模板匹配实现多目标跟踪

SORT多目标跟踪算法

SORT是一种简单的在线实时多目标跟踪算法。文章要点为:

  • 以 IoU 作为前后帧间目标关系度量指标;
  • 利用卡尔曼滤波器预测当前位置
  • 通过匈牙利算法关联检测框到目标;
  • 应用试探期甄别虚检;

具体的代码分析,可以参考:SORT 多目标跟踪算法笔记。本人还没有这么深入的理解。
总之我们可以通过:

mot_tracker = Sort()

调用Sort检测算法。

接着使用以下命令进行参数更新:

trackers = mot_tracker.update(match_result)

其中match_result的格式为:

参数dets:格式为[[x1,y1,x2,y2,score],[x1,y1,x2,y2,score],…]的 numpy 检测数组。

返回的trackers 包含最终的结果,主要包括被跟踪物体的位置信息和序号,得到这些之后,我们可以在视频帧中进行标注。

基于模板匹配的目标检测

这里的目标检测使用最基本的基于模板匹配的方法。

result = cv2.matchTemplate(target, tpl, method)

基于模板匹配的代码如下

def template_demo(tpl, target, method = cv2.TM_CCORR_NORMED):
    th, tw = tpl.shape[:2]# 取高宽,不取通道 模板高宽
    global fake_color
    result = cv2.matchTemplate(target, tpl, method) # 每一个点的匹配度
    kcf_result = np.copy(result)

    kcf_result = np.uint8(np.power((kcf_result+1)/2, 1.5)*250)
    ball_center = loc_max(kcf_result, 170) # 得到中心点坐标
    im_color = cv2.applyColorMap(kcf_result, cv2.COLORMAP_JET)

    match_result = []
    for i in range(len(ball_center)):
        center_y = int(ball_center[i][0] + ball_center[i][2]/2)
        center_x = int(ball_center[i][1] + ball_center[i][3]/2)
        match_result.append([ int(center_y),int(center_x),  int(center_y+th),int(center_x+tw), result[center_x, center_y]])
    cv2.imshow('kcf', im_color)
    fake_color.write(im_color)
    return match_result # [[x1,y1,x2,y2,score],[x1,y1,x2,y2,score],...]

def loc_max(kcf_result, threshold):
    ball_center = []
    global erzhi
    ret, kcf_threshold = cv2.threshold(kcf_result, threshold, 255, cv2.THRESH_BINARY)
    #创建矩形结构单元
    g=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
    #形态学处理,开运算
    img_open=cv2.morphologyEx(kcf_threshold,cv2.MORPH_OPEN,g)
    _, contours, hierarchy = cv2.findContours(img_open, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    for cnt in contours:
        bounding_boxes = cv2.boundingRect(cnt)
        cv2.rectangle(img_open, (bounding_boxes[0], bounding_boxes[1]), (bounding_boxes[0]+bounding_boxes[2], bounding_boxes[1]+bounding_boxes[3]),(255,0,0))
        ball_center.append(bounding_boxes)
    cv2.imshow('threshold', img_open)
    img_open = np.expand_dims(img_open, 2)
    img_open = np.concatenate((img_open, img_open, img_open), axis=2)
    erzhi.write(img_open)
    return ball_center

模板匹配结果与SORT算法融合

mot_tracker = Sort()
color = np.uint8(np.random.rand(32, 3)*255)
while True:
    ok, frame = video.read()
    bar.update(1)
    if ok:
        match_result = template_demo(ROI, frame, method=cv2.TM_CCOEFF_NORMED)
        # print(match_result)
        match_result = np.array(match_result)
        trackers = mot_tracker.update(match_result)
        for tracker in trackers:
            color_tracker = ( int(color[int(tracker[4]%30)][0]), int(color[int(tracker[4]%30)][1]), int(color[int(tracker[4]%30)][2]))
            cv2.rectangle(frame, (int(tracker[0]), int(tracker[1])), (int(tracker[2]), int(tracker[3])), color_tracker, 2)
            cv2.putText(frame, str(int(tracker[4])),(int(tracker[0]/2+tracker[2]/2), int(tracker[1]/2+tracker[3]/2)), cv2.FONT_HERSHEY_SIMPLEX, 1, (255,0,0))
        
        result.write(frame)
        cv2.imshow('frame', frame)
        if cv2.waitKey(3) == 27:
            break
    else:
        break

完整代码

代码我放在了:SORT_matchTemplate
以及演示的原始视频:red_ball.flv
使用的时候直接把这三个文件放在同一文件夹下,执行red_ball.py即可。

如果有什么疑问,还请留言。

评论 31
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值