高空无人机视角下的路口车辆与行人检测跟踪与轨迹刻画

Posted Wupke

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高空无人机视角下的路口车辆与行人检测跟踪与轨迹刻画相关的知识,希望对你有一定的参考价值。

背景需求

背景:
项目需要在高空视角下,对视频流中的行人与车辆进行跟踪与轨迹记录,理想的状态如下所示:


完全达到上述实际达到可能有点难度。但是可以逐步尝试实现。

可参考的方法

1、 opencv + python 实现目标跟踪的方法:

这里是为了更加准确获取具体目标的坐标信息,减小检测模型带来的误差因素,所以考虑单目标的跟踪检测。先用人工标注视频流的第一帧,选择要跟踪的目标,之后进行逐帧跟踪并刻画轨迹。

采用opencv + python 结合的方法

  • 环境依赖
  • opencv-python==3.4.9.33
  • contrib==0.3.0
  • pytho==3.7

主要代码

① main.py


# -*- coding: utf-8 -*-
# @Time    : 2021/09/03
# @Author  : Wupke
# Purpose  :  Single-object detection & Trajectory tracking  using opencv and python

import cv2
from items import MessageItem
import time
import numpy as np

class ObjectTracker(object):
    def __init__(self, dataSet):
        self.cascade = cv2.CascadeClassifier(dataSet)

    def track(self, frame):
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        faces = self.cascade.detectMultiScale(gray, 1.03, 5)
        for (x, y, w, h) in faces:
            cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
        return frame

class Tracker(object):
    '''
    对于指定目标,进行后续跟踪
    '''
    def __init__(self, tracker_type="BOOSTING", draw_coord=True):
        '''
        初始化追踪器种类
        '''
        # 查看opencv版本
        (major_ver, minor_ver, subminor_ver) = (cv2.__version__).split('.')
        self.tracker_types = ['BOOSTING', 'MIL', 'KCF', 'TLD', 'MEDIANFLOW', 'GOTURN']
        self.tracker_type = tracker_type
        self.isWorking = False
        self.draw_coord = draw_coord
        # 构造追踪器
        if int(minor_ver) < 3:
            self.tracker = cv2.Tracker_createBoosting(tracker_type)
        else:
            if tracker_type == 'BOOSTING':
                self.tracker = cv2.TrackerBoosting_create()
            if tracker_type == 'MIL':
                self.tracker = cv2.TrackerMIL_create()
            if tracker_type == 'KCF':
                self.tracker = cv2.TrackerKCF_create()
            if tracker_type == 'TLD':
                self.tracker = cv2.TrackerTLD_create()
            if tracker_type == 'MEDIANFLOW':
                self.tracker = cv2.TrackerMedianFlow_create()
            if tracker_type == 'GOTURN':
                self.tracker = cv2.TrackerGOTURN_create()

    def initWorking(self, frame, box):
        '''
        追踪器工作初始化,frame:初始化追踪画面,box:追踪的区域
        '''
        if not self.tracker:
            raise Exception("追踪器未初始化")
        status = self.tracker.init(frame, box)
        if not status:
            raise Exception("追踪器工作初始化失败")
        self.coord = box
        self.isWorking = True

    def track(self, frame):
        '''
        开启追踪,记录记录追踪目标坐标
        '''
        message = None
        
        if self.isWorking:
            status, self.coord = self.tracker.update(frame)
            if status:
                message = {"coord": [((int(self.coord[0]), int(self.coord[1])),
                                      (int(self.coord[0] + self.coord[2]), int(self.coord[1] + self.coord[3])))]}
                if self.draw_coord:
                    center_x = ''
                    center_y = ''
                    p1 = (int(self.coord[0]), int(self.coord[1]))
                    p2 = (int(self.coord[0] + self.coord[2]), int(self.coord[1] + self.coord[3]))
                    cv2.rectangle(frame, p1, p2, (255, 0, 0), 2, 1)
                    message['msg'] = "is tracking"
                    center_x,center_y=int((p1[0]+p2[0])/2),int((p1[1]+p2[1])/2)
        return MessageItem(frame, message),center_x,center_y        # 导出绘制的跟踪框中心坐标
        
if __name__ == '__main__':

    a = ['BOOSTING', 'MIL', 'KCF', 'TLD', 'MEDIANFLOW', 'GOTURN']
    tracker = Tracker(tracker_type="KCF")   # 跟踪器可以切换其他的来看效果
    # video = cv2.VideoCapture(0)
    cap = cv2.VideoCapture("E:/Desktop/D_0239.mp4")
    
    '''获得视频流帧数,保存跟踪的视频,保存处理后的视频,注意保存处理后的视频画面帧的大小是否改变等等问题,否则会储存视频失败
    '''
    fps,w,h, = int(cap.get(5)),int(cap.get(3)),int(cap.get(4))
    print('fps: ', fps,'w: ', w,'h: ', h)

    fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v') 
    res_path = 'E:/Desktop/实验室文字编辑工作/20210827无人机/demo/result000.mp4'
    res = cv2.VideoWriter(res_path,fourcc,fps,(w,h),True) 
   
    i=0
    car_tri=[]    # 存储系列轨迹点中心的坐标
    while True:
        ret, frame = cap.read()
        frame = cv2.resize(frame, (1200, 800))

        if i==0:
            # 暂停第一帧进行手工标注
                bbox = cv2.selectROI(frame, False)
                tracker.initWorking(frame, bbox)
        i+=1
        #第二帧以后,开始保存每一帧的跟踪框中心坐标
        center=[]
        if (ret):
            item = tracker.track(frame)[0]  # 画面
            x,y= tracker.track(frame)[1:]  # 第二帧以后
            center.append(x)
            center.append(y)
            car_tri.append(center)
            # # 限制轨迹最大长度
            # if len(car_tri)> 300:
            #     for k in range(len(car_tri) - 300):
            #         del car_tri[k]

            # # # 绘制轨迹
            if len(car_tri) > 2:
                for j in range(1, len(car_tri) - 1):
                    pot1_x = car_tri[j][0]
                    pot1_y = car_tri[j][1]
                    pot2_x = car_tri[j + 1][0]
                    pot2_y = car_tri[j + 1][1]
                    cv2.line(frame, (pot1_x, pot1_y), (pot2_x, pot2_y), (255,0,0), 2)
            # print(x,y)
            frame=item.getFrame()
            cv2.imshow("track", frame)
            frame = cv2.resize(frame, (w, h))    # 还原视频的原始尺寸
            res.write(frame)
            k = cv2.waitKey(1) & 0xff
            if k == 27:
                break
    cap.release()
    res.release()
    cv2.destroyAllWindows()

② items.py


#encoding=utf-8
import json
'''
封装类
'''
class MessageItem(object):
    #用于封装信息的类,包含图片和其他信息
    def __init__(self,frame,message):
        self._frame = frame
        self._message = message
    def getFrame(self):
        #图片信息
        return self._frame
    def getMessage(self):
        #文字信息,json格式
        return self._message
    # def getBase64Frame(self):
        #返回base64格式的图片,将BGR图像转化为RGB图像
        # jepg = IOUtil.array_to_bytes(self._frame[...,::-1])
        # return IOUtil.bytes_to_base64(jepg)
    def getBase64FrameByte(self):
        #返回base64格式图片的bytes
        return bytes(self.getBase64Frame())
    def getJson(self):
        #获得json数据格式
        dicdata = {"frame":self.getBase64Frame().decode(),"message":self.getMessage()}
        return json.dumps(dicdata)
    def getBinaryFrame(self):
        return IOUtil.array_to_bytes(self._frame[...,::-1])


检测效果

  • 车辆

  • 行人

2、 dlib库单目标检测方法

还有dlib库中的dlib.correlation_tracker()类实现目标跟踪的方法
dlib官方文档入口:
http://dlib.net/python/index.html#dlib.correlation_tracker
相关博文:https://blog.csdn.net/hongbin_xu/article/details/78359663

3、 深度学习方法

采用深度学习方法,先进行检测,在结合跟踪算法进行轨迹刻画。在这种视角下,需要重新训练检测的模型,而且行人目标较小,检测难度大,效果不敢说(尝试yolov+deepsort)。正在整合,后续会更新。

代码

在这里插入代码片

效果

后续更新。。。。。。

推荐相关目标追踪的博文

https://blog.csdn.net/qq_35488769/article/details/79103264
https://blog.csdn.net/hongbin_xu/article/details/78359663
https://blog.csdn.net/MHxiaoS/article/details/106675585

高空无人机视角下的检测跟踪数据集网址:
① https://www.ind-dataset.com/
② http://aiskyeye.com/download/multi-object-tracking_2021/

以上是关于高空无人机视角下的路口车辆与行人检测跟踪与轨迹刻画的主要内容,如果未能解决你的问题,请参考以下文章

即将截止|图像识别/数据融合/行人和车辆的检测与跟踪算法技术精讲|牛喀学城

行人车辆检测与计数系统(Python+YOLOv5深度学习模型+清新界面)

实时车辆行人多目标检测与跟踪系统-上篇(UI界面清新版,Python代码)

行人车辆检测与计数系统(Python+YOLOv5深度学习模型+清新界面)

基于opencv对高空拍摄视频消抖处理

#yyds干货盘点#项目实战 <-; DeepSORT算法实现车辆和行人跟踪计数和是否道路违规检测