deepsort标注单个跟踪目标方法

deepsort可以跟踪图像中多个目标,某些应用下需要跟踪其中某个感兴趣的目标。此处对deepsort程序的变化是,用鼠标点击感兴趣目标,对此目标加特别标注,使其跟踪框加粗而明显,有助于单独提取感兴趣目标的坐标。
本博文用于记录实现过程,便于以后再用到此功能时,方便查找。python函数太多,留点记录防止遗忘。希望CSDN长命百岁。
deepsort中 track.py每帧处理图像过程:

TTS = Target_designation(title='', img =[], target_xy = np.array([0, 0]), 
            new_click = False, target_label = 0)       # 指定目标参数类初始化
for frame_idx, (path, img, ...) in enumerate(dataset): # 帧处理起始点
    pred = model(img, ...)  # yolov5 detector
    pred = non_max_suppression(pred, ...)
    det = pred
    annotator = Annotator(im0, line_width=1, pil=not ascii) #初始化Annotator类的实例。
    outputs = deepsort.update(det, im0)  # deepsort track
    for j, (output, conf) in enumerate(zip(outputs, confs)):
        bboxes = output[0:4]   # each track box
        id = output[4]          # track box id
        annotator.box_label(bboxes, id, ...) # 显示跟踪框
        cv2.setMouseCallback(str(p), TTS.on_EVENT_LBUTTONDOWN) # 调用回调函数
cv2.imshow(str(p), im0)
cv2.waitKey(20)

对每帧图像img,yolov5检测出目标pred,再换成det,经deepsort跟踪过程,得到output,为det的跟踪框:bboxes和id。针对每个bbox,id,采用标注函数annotator.box_label在图像im0上画出。最后每帧图像显示:

cv2.imshow(title=str(p), img=im0)

cv2.imshow有两个参数,im0是显示的图像,title是显示窗口。
在bbox的循环中,插入鼠标回调函数cv2.setMouseCallback(),其中指定在哪个窗口,p是输入视频的路径,窗口title标题显示此路径。

在deepsort跟踪图像中指定目标。如图,用鼠标指定有跟踪框的目标,点击后该跟踪框显示为绿色粗线框。

回调函数cv2.setMouseCallback指定了鼠标响应函数TTS.on_EVENT_LBUTTONDOWN,TTS是类Target_designation的实例,将on_EVENT_LBUTTONDOWN作为类 Target_designation中的函数定义。

def on_EVENT_LBUTTONDOWN(self, event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:  # 鼠标左键按下时候的操作
        xy = "%d,%d" % (x, y)
        print(xy) # 控制台显示当前像素坐标
        cv2.circle(self.img, (x, y), 10, (255, 0, 0), thickness=-1) # 画实心圆
        self.target_xy=np.array([x, y])
        self.new_click = True
        cv2.imshow(self.title, self.img)

在此定义类Target_designation,作为指定目标参数保存。setMouseCallback的响应函数放到此类中,有助于将鼠标点击获得的图像窗口中指定目标的xy坐标存入类变量,供其他函数使用。
响应函数中,鼠标左键按下时,cv2.circle()画实心圆,后面需跟随imshow才能显示。imshow需要两个参数,而响应函数的参数中,只有param来传递一个参数。因此用类变量给出这两个参数更好,可以省略param参数的使用。
当然响应函数中可不画实心圆,只是为直观显示点击效果。当完成鼠标点击指定目标,显示绿色粗框的过程后,可以去除画实心圆语句。
Target_designation类的初始化:

class Target_designation:
    def __init__(self, title, img, target_xy, new_click, target_label):
        self.target_xy = np.array([0,0])
        self.new_click = False
        self.target_label = 0
        self.title = " "
        self.img = []

从外部对类变量的改变:

def save_target(self, title, img, target_xy, new_click, target_label ):
    self.target_xy = target_xy   #指定目标的坐标
    self.new_click = new_click  #鼠标左键按下指示
    self.target_label = target_label #指定目标id
    self.title = title  # 窗口
    self.img = img  # 窗口中的图像
    return self

判断当前目标框是否指定目标:

def target_juge(self, bbox, id ):
    if self.new_click:
        bbox_center = np.array([(bbox[2]-bbox[0])/2, (bbox[3]-bbox[1])/2])
        target_center = self.target_xy-np.array([bbox[0], bbox[1]])
        dif_center1 = bbox_center - target_center
        dif_center2= hypot(dif_center1[0], dif_center1[1])
        # p4 is the diagonal of det box
        p1 = bbox[0:2]
        p2 = bbox[2:4]
        p3 = p1 - p2
        p4 = hypot(p3[0], p3[1]) # hypot计算两个坐标点间的距离sqrt(x^2+y^2)
        if dif_center2 <= 0.25*p4:
            if id:
                self.target_label = id
                self.new_click = False

比较当前目标框中心与指定目标中心的距离,若小于当前目标框对角线的1/4,则认为所点击的指定目标就是当前目标框,判断成功则将当前目标框id保存为指定目标id,在标注函数annotator.box_label中,目标框id = 指定目标id时,将目标框显示为绿色粗框,与其他目标框相区别。
Target_designation类实例语句应在帧循环之外定义,否则每帧图像初始化后,将失去之前保存的指定目标参数值。

你可能感兴趣的:(人工智能,yolov5,python,pytorch,深度学习)