基于KCF和MobileNet V2以及KalmanFilter的摄像头监测系统

简介

这是一次作业。Tracking这一块落后Detection很多年了,一般认为Detection做好了,那么只要能够做的足够快,就能达到Tracking的效果了,实则不然,现在最快的我认为就是一些可以在手机等arm下使用的轻量神经网络了,但是其牺牲了准确性,依然达不到追踪的效果,因为你无法将多次识别的Object视为统一对象画出运动轨迹。Tracking与Detection的根本区别在于Tracking可以很快的识别,因为基本上只需要识别一次,然后调用跟踪算法对目标进行跟进就可以了,而跟踪算法只需要在目标所在位置附近进行搜‘索判断是否存在目标就可以了,不用像Detection那样整张图遍历来寻找目标。而本篇也是使用的是轻量神经网络MobileNet和MIL以及KCF追踪算法,两者结合使用,达到了一定的追踪效果。

由于比赛需要,我改了一改,做成了robomaster的追踪程序。。

难点&解决

多个人的追踪

对于同时能够追踪多目标,我的想法是写一个Person类,实例化出不同的person对象,对个person对象只完成自己对象本身的追踪工作,不会干扰到其他对象的追踪。在对象走出视频流区域一段时间(可以作为参数设置)后将对象销毁。对于初始化问题,可以采用MobieNet的训练结果进行对象参数的初始化,当视频流中没有目标时只运行MobileNet的识别即可。识别必须每隔一段时间进行一次,将那些识别出的人与我们已经实例化出的人进行距离比较,相当于一个匹配,已有的保留,没有的再继续进行实例化,然后追踪。

人从各个方向运动的追踪

由于人可能从各个方向进入视频流,因此对分类器的要求会比较高,所以我们需要训练大量的实地场景的各种姿态进入视频流的图片,当然,由于宿舍空间有限,我没办法做出人从监视器各个角度各个方向进出的训练集。因此这个问题其实有待解决,但是我觉得可以通过丰富训练集来解决(废话)。

人遮挡状态下的追踪

对于遮挡状态下的追踪,我打算这么解决,遮挡首先分为短时间遮挡和长时间遮挡,对于短时间遮挡我们可以采用消失计时的方法,设置一个阈值,在消失阈值范围内输出原框,或者原来有速度进行一个预测,但是预测肯定会出问题,因为预测是按照前一帧的速度来预测的,因此预测的框会一直按照速度方向平移,所以速度应该在预测的时候逐渐减小,这样才能避免一直有速度的预测。还有就是可以通过卡尔曼滤波来做,这个我有做的打算,正在研究他的论文。这个问题属于Long-Term-Tracking问题,现有的方法有的是采用分块识别,就是分别识别人的某一部分,然后把识别到的结果合起来以及其他方法,具体还在看。

光照条件变化时候的追踪

对于光照变化的时候的追踪,我觉得这就完全可以交给我们的神经网络,神经网络提取的特征是可以保证在多尺度和各种光照条件下实现较高准确度的分类的,因此,在光照较暗和光照较强的条件下我们的神经网络都可以取得比较好的效果,因此是可以完成识别的任务的。

KCF & KalmanFilter

KCF

KCF算法是核相关滤波的简称,利用循环移位进行稠密采样,FFT快速变换进行分类器的训练,同时结合了多通道的HOG特征,大致的流程是,先利用循环矩阵不断对图像移位,得到多个样本,在第t帧中的当前位置附近利用这些样本训练一个分类器,这个分类器可以对框中是否有人做出一个概率响应,因此当我们来到下一帧的时候呢,先用循环矩阵对前一帧的区域进行循环移位得到若干样本,然后用前一帧训练的分类器分类得到输出响应,以响应最大的作为预测位置,然后再训练,再预测。这个算法的推导我会专门写一篇博客。

Kalman波波

状态方程:

测量方程:

xk是状态向量,zk是测量向量,Ak是状态转移矩阵,uk是控制向量,Bk是控制矩阵,wk是系统误差(噪声),Hk是测量矩阵,vk是测量误差(噪声)。wk和vk都是高斯噪声,即

实际应用的推导过程如下:


使用

关于使用KCF,我是写了个类,这样可以做多目标的跟踪,不然就只能单目标啦。而且加入了kalmanfilter来预测并且修正观测值。

class Person:def __init__(self, bg, bbox,delta_time = 0.2 ,acc = 2):self._zs = 0self._bbox = bboxself._tracker = cv.TrackerKCF_create()self._center = (int(bbox[0]+bbox[2]/2), int(bbox[1]+bbox[3]/2))self._mask = np.zeros(bg.shape, dtype = np.uint8)self._shape = bg.shapeself._no_time = 0self._tracker.init(bg,bbox)self._frame = bgself._predicted = Noneself.kalman = cv.KalmanFilter(4,2,0)# 状态空间4D 分别是x y vx vy,测量空间2D 分别是 x yself.kalman.transitionMatrix = np.array([[1,0,delta_time,0],[0,1,0,delta_time],[0,0,1,0],[0,0,0,1]],dtype = np.float32)self.kalman.measurementMatrix = np.array([[1,0,0,0],[0,1,0,0]],dtype = np.float32)self.kalman.statePre = np.array([[self._center[0]],[self._center[1]],[0],[0]],dtype = np.float32)self.kalman.statePost = np.array([[self._center[0]],[self._center[1]],[0],[0]],dtype = np.float32)self.kalman.processNoiseCov = acc * np.array([[0.25*delta_time**4,0,0.5*delta_time**3,0],[0,0.25*delta_time**4,0,0.5*delta_time**3],[0.5*delta_time**3,0,delta_time**2,0],[0,0.5*delta_time**3,0,delta_time**2]],dtype = np.float32)def update(self,new_bbox,center):self._bbox = new_bboxself._center = centerdef precess(self,src):self._zs = self._zs + 1h,w = self._shape[:2]frame = copy.copy(src)padding = 5 # paddingret, bbox = self._tracker.update(frame) # bbox: x y w hp1,p2 = (int(bbox[0]),int(bbox[1])),(int(bbox[0])+int(bbox[2]),int(bbox[1])+int(bbox[3]))center = (int((p1[0]+p2[0])/2),int((p1[1]+p2[1])/2))global person_countif self._no_time == 20:self._no_time = 0self._mask = np.zeros(self._shape,dtype=np.uint8)self._frame = srcreturn (False,src)if ret and p1[0]>=padding and p1[1]<= (w-padding):#and int(bbox[0])>=padding and int(bbox[0] + bbox[2])<= (w-padding) #and int(bbox[1])>=padding and int(bbox[1] + bbox[3])<=(h-padding)self._no_time = 0s = np.array([[np.float32(center[0])],[np.float32(center[1])]])self.kalman.correct(s)center = self.kalman.predict().astype(np.int)#print(center[0],center[1])center = (center[0,0],center[1,0])cv.line(self._mask,self._center,center,(255,255,0),2)mmask = cv.cvtColor(self._mask.astype(np.uint8),cv.COLOR_BGR2GRAY)mmask = cv.bitwise_not(mmask)self._frame = cv.add(frame, self._mask, mask = mmask)self.update(bbox,center)#self._predicted = [self._bbox[i]+self._speed[i] if i<2 else self._bbox[i] for i in range(4)]#predict_1,predict_2 = (int(self._predicted[0]),int(self._predicted[1])),(int(self._predicted[0])+int(self._predicted[2]),int(self._predicted[1])+int(self._predicted[3]))#cv.rectangle(self._frame,predict_1,predict_2,(0,255,255),2,1) # 画预测框#cv.putText(self._frame,"predicted",predict_1,cv.FONT_HERSHEY_SIMPLEX,0.5,(0,255,255),2)cv.rectangle(self._frame, p1, p2, (255, 0, 0), 2, 1) # 画识别框cv.putText(self._frame,"recognized",p2,cv.FONT_HERSHEY_SIMPLEX,0.5,(255,0,0),2)#cv.waitKey(10)return (True,self._frame)else:ret,bbox = recg_car(frame)if ret:p1,p2 = (int(bbox[0]),int(bbox[1])),(int(bbox[0])+int(bbox[2]),int(bbox[1])+int(bbox[3]))center = (int((p1[0]+p2[0])/2),int((p1[1]+p2[1])/2))s = np.array([[np.float32(center[0])],[np.float32(center[1])]])self.kalman.correct(s)center = self.kalman.predict().astype(np.int)center = (center[0,0],center[1,0])cv.line(self._mask,self._center,center,(255,255,0),2)mmask = cv.cvtColor(self._mask.astype(np.uint8),cv.COLOR_BGR2GRAY)mmask = cv.bitwise_not(mmask)self._frame = cv.add(frame, self._mask, mask = mmask)self.update(bbox,center)cv.rectangle(self._frame, p1, p2, (255, 0, 0), 2, 1) # 画识别框cv.putText(self._frame,"recognized",p2,cv.FONT_HERSHEY_SIMPLEX,0.5,(255,0,0),2)return (True,self._frame)else:self._no_time = self._no_time + 1mmask = cv.cvtColor(self._mask.astype(np.uint8),cv.COLOR_BGR2GRAY)mmask = cv.bitwise_not(mmask)self._frame = cv.add(frame, self._mask, mask = mmask)return (True,self._frame)

使用MobileNet V2模型进行训练和预测

关于训练过程我就不一一介绍了,之前的博客也有写到怎么做,直接贴代码(完整的)。

import cv2 as cv
import sys
import numpy as np
import os
import copy
import tensorflow as tf
sys.path.append("..")
from utils import label_map_util
from utils import visualization_utils as vis_util
DEBUG = False # 表示不是调试模式
THRE_VAL = 0.4 # 这里设置的是置信度的阈值,如果大于这个阈值就在图像里面把他给框出来
# ['BOOSTING', 'MIL', 'KCF', 'TLD', 'MEDIANFLOW', 'GOTURN']
#tracker = cv.TrackerKCF_create()
#tracker = cv.TrackerMIL_create()
PATH_TO_CKPT ='/home/xueaoru/trace/car/frozen_inference_graph.pb' #网络结构配置文件
PATH_TO_LABELS = '/home/xueaoru/trace/car/label_map.pbtxt' # 标签映射关系配置文件
NUM_CLASSES = 2 # 分类数目
label_map = label_map_util.load_labelmap(PATH_TO_LABELS) # 调用函数加载labelmap,相当于把文本转换成了json文件
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, use_display_name=True)
# 上面一句是把每个labelmap格式的数据转换为dict类型的数据,每隔id对应一个输出的name
category_index = label_map_util.create_category_index(categories) # 得到每个id,也就是key
detection_graph = tf.Graph() #加载默认图
with detection_graph.as_default():od_graph_def = tf.GraphDef()with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:# 加载网络模型serialized_graph = fid.read()od_graph_def.ParseFromString(serialized_graph)tf.import_graph_def(od_graph_def, name='')sess = tf.Session(graph=detection_graph)# 运行开启session
image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')
detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0')
detection_scores = detection_graph.get_tensor_by_name('detection_scores:0')
detection_classes = detection_graph.get_tensor_by_name('detection_classes:0')
num_detections = detection_graph.get_tensor_by_name('num_detections:0')
cap = cv.VideoCapture("/home/xueaoru/下载/red1.mp4")
#cap = cv.VideoCapture(1)
person_exist = False
class Person:def __init__(self, bg, bbox,delta_time = 0.2 ,acc = 2):self._zs = 0self._bbox = bboxself._tracker = cv.TrackerKCF_create()self._center = (int(bbox[0]+bbox[2]/2), int(bbox[1]+bbox[3]/2))self._mask = np.zeros(bg.shape, dtype = np.uint8)self._shape = bg.shapeself._no_time = 0self._tracker.init(bg,bbox)self._frame = bgself._predicted = Noneself.kalman = cv.KalmanFilter(4,2,0)# 状态空间4D 分别是x y vx vy,测量空间2D 分别是 x yself.kalman.transitionMatrix = np.array([[1,0,delta_time,0],[0,1,0,delta_time],[0,0,1,0],[0,0,0,1]],dtype = np.float32)self.kalman.measurementMatrix = np.array([[1,0,0,0],[0,1,0,0]],dtype = np.float32)self.kalman.statePre = np.array([[self._center[0]],[self._center[1]],[0],[0]],dtype = np.float32)self.kalman.statePost = np.array([[self._center[0]],[self._center[1]],[0],[0]],dtype = np.float32)self.kalman.processNoiseCov = acc * np.array([[0.25*delta_time**4,0,0.5*delta_time**3,0],[0,0.25*delta_time**4,0,0.5*delta_time**3],[0.5*delta_time**3,0,delta_time**2,0],[0,0.5*delta_time**3,0,delta_time**2]],dtype = np.float32)def update(self,new_bbox,center):self._bbox = new_bboxself._center = centerdef precess(self,src):self._zs = self._zs + 1h,w = self._shape[:2]frame = copy.copy(src)padding = 5 # paddingret, bbox = self._tracker.update(frame) # bbox: x y w hp1,p2 = (int(bbox[0]),int(bbox[1])),(int(bbox[0])+int(bbox[2]),int(bbox[1])+int(bbox[3]))center = (int((p1[0]+p2[0])/2),int((p1[1]+p2[1])/2))global person_countif self._no_time == 20:self._no_time = 0self._mask = np.zeros(self._shape,dtype=np.uint8)self._frame = srcreturn (False,src)if ret and p1[0]>=padding and p1[1]<= (w-padding):#and int(bbox[0])>=padding and int(bbox[0] + bbox[2])<= (w-padding) #and int(bbox[1])>=padding and int(bbox[1] + bbox[3])<=(h-padding)self._no_time = 0s = np.array([[np.float32(center[0])],[np.float32(center[1])]])self.kalman.correct(s)center = self.kalman.predict().astype(np.int)#print(center[0],center[1])center = (center[0,0],center[1,0])cv.line(self._mask,self._center,center,(255,255,0),2)mmask = cv.cvtColor(self._mask.astype(np.uint8),cv.COLOR_BGR2GRAY)mmask = cv.bitwise_not(mmask)self._frame = cv.add(frame, self._mask, mask = mmask)self.update(bbox,center)#self._predicted = [self._bbox[i]+self._speed[i] if i<2 else self._bbox[i] for i in range(4)]#predict_1,predict_2 = (int(self._predicted[0]),int(self._predicted[1])),(int(self._predicted[0])+int(self._predicted[2]),int(self._predicted[1])+int(self._predicted[3]))#cv.rectangle(self._frame,predict_1,predict_2,(0,255,255),2,1) # 画预测框#cv.putText(self._frame,"predicted",predict_1,cv.FONT_HERSHEY_SIMPLEX,0.5,(0,255,255),2)cv.rectangle(self._frame, p1, p2, (255, 0, 0), 2, 1) # 画识别框cv.putText(self._frame,"recognized",p2,cv.FONT_HERSHEY_SIMPLEX,0.5,(255,0,0),2)#cv.waitKey(10)return (True,self._frame)else:ret,bbox = recg_car(frame)if ret:p1,p2 = (int(bbox[0]),int(bbox[1])),(int(bbox[0])+int(bbox[2]),int(bbox[1])+int(bbox[3]))center = (int((p1[0]+p2[0])/2),int((p1[1]+p2[1])/2))s = np.array([[np.float32(center[0])],[np.float32(center[1])]])self.kalman.correct(s)center = self.kalman.predict().astype(np.int)center = (center[0,0],center[1,0])cv.line(self._mask,self._center,center,(255,255,0),2)mmask = cv.cvtColor(self._mask.astype(np.uint8),cv.COLOR_BGR2GRAY)mmask = cv.bitwise_not(mmask)self._frame = cv.add(frame, self._mask, mask = mmask)self.update(bbox,center)cv.rectangle(self._frame, p1, p2, (255, 0, 0), 2, 1) # 画识别框cv.putText(self._frame,"recognized",p2,cv.FONT_HERSHEY_SIMPLEX,0.5,(255,0,0),2)return (True,self._frame)else:self._no_time = self._no_time + 1mmask = cv.cvtColor(self._mask.astype(np.uint8),cv.COLOR_BGR2GRAY)mmask = cv.bitwise_not(mmask)self._frame = cv.add(frame, self._mask, mask = mmask)return (True,self._frame)def recg_car(frame):image_expanded = np.expand_dims(frame, axis=0)(boxes, scores, classes, num) = sess.run([detection_boxes, detection_scores, detection_classes, num_detections],feed_dict={image_tensor: image_expanded})score = np.squeeze(scores)max_index = np.argmax(score)score = score[max_index]# print(score)if score > THRE_VAL:box = np.squeeze(boxes)[max_index]#(ymin,xmin,ymax,xmax)h,w,_ = frame.shapemin_point = (int(box[1]*w),int(box[0]*h))max_point = (int(box[3]*w),int(box[2]*h))bbox = (min_point[0], min_point[1], max_point[0]-min_point[0], max_point[1] - min_point[1])return True,bboxelse:return False,None
ret, frame = cap.read()
if not ret:print("err")sys.exit()
ret,bbox = recg_car(frame)
person = Person(frame,bbox)
while True:ret,frame = cap.read()time = cv.getTickCount()if not ret:breakperson_exist,frame = person.precess(frame)cv.imshow("frame",frame)time = cv.getTickCount() - timeprint("处理时间:"+str(time*1000/cv.getTickFrequency())+"ms")key = cv.waitKey(1) & 0xffif key ==27:break
cap.release()
cv.destroyAllWindows()

转载于:https://www.cnblogs.com/aoru45/p/10281739.html

[Tracking] KCF + KalmanFilter目标跟踪相关推荐

  1. kcf 跟随_基于YOLO和KCF的目标跟踪算法研究

    1. 引言 随着AI技术的不断发展,其子领域计算机视觉技术也获得了突飞猛进的进步,计算机视觉即通过机器实现"人眼"对事物的测量和判别能力.目前,计算机视觉技术主要应用于智能视频监控 ...

  2. UDT(【CVPR2019】Unsupervised Deep Tracking无监督目标跟踪)

    UDT是中科大.腾讯AI lab和上交的研究者提出的无监督目标跟踪算法.仔细阅读过这篇文章之后,写下一篇paper reading加深印象. 论文标题:Unsupervised Deep Tracki ...

  3. Online Object Tracking Benchmark(OTB)目标跟踪系统评估方式

    主要涉及到一些评估方式的讲解: 评估数据集: OTB50和OTB100(OTB50这里指OTB-2013,OTB100这里指OTB-2015) Wu Y, Lim J, Yang M H. Onlin ...

  4. 飞桨Tracking目标跟踪库开源!涵盖业界主流的VOT算法,精准检测动态目标轨迹...

    点击左上方蓝字关注我们 如何精准理解运动目标的行为呢?一起看看下面的视频,感受VOT技术的神奇吧! 从短视频中可以发现,视频中的目标是运动的,且不断变化.对于物体遮挡.形变.背景杂斑.尺度变换.快速运 ...

  5. KCF目标跟踪方法分析与总结

    KCF目标跟踪方法分析与总结 两个竖杠是什么数学符号    就是这个 | |  这个符号叫做范数,它事实上是由线性赋范空间到非负实数的映射 在线性赋范空间中,它可以表示空间中的点与原点间的距离,两点间 ...

  6. Object Tracking using OpenCV (C++/Python)(使用OpenCV进行目标跟踪)

    本博客翻译搬运自https://www.learnopencv.com/object-tracking-using-opencv-cpp-python,用于初入目标跟踪的新手学习,转贴请注明! 使用O ...

  7. 【目标跟踪】Long-term Correlation Tracking 阅读笔记

    Long-term Correlation Tracking 论文地址: https://www.cv-foundation.org/openaccess/content_cvpr_2015/pape ...

  8. 【专知荟萃18】目标跟踪Object Tracking知识资料全集(入门/进阶/论文/综述/视频/专家,附查看)

    原创: 专知内容组 专知 2017-11-18 点击上方"专知"关注获取专业AI知识! [导读]主题荟萃知识是专知的核心功能之一,为用户提供AI领域系统性的知识学习服务.主题荟萃为 ...

  9. Python Opencv-contrib Camshift kalman卡尔曼滤波 KCF算法 CSRT算法 目标跟踪实现

    本文为原创文章,转载请注明出处. 本次课题实现目标跟踪一共用到了三个算法,分别是Camshift.Kalman.CSRT,基于Python语言的Tkinter模块实现GUI与接口设计,项目一共包含三个 ...

最新文章

  1. Spring 系列: Spring 框架简介
  2. mysql error 1594_MySQL 1594 异常解决办法
  3. 如何学好C、C++------思维方式的转变
  4. 听说你想去大厂看妹子,带你看看阿里软件测试岗四轮面试是怎么样的?
  5. 成都工业学院计算机工程学院院长,青春的交接礼——成都工业学院计算机工程学院...
  6. 【工具】switchhost
  7. 2017-03-10Git版本回退
  8. NPOI 将DataGridView导出到Excel
  9. 第五章(1)Libgdx应用框架之生命周期
  10. java http url 编码_Java中的HTTP URL地址编码
  11. 国产联盟链 Fisco-Bcos 调技术研报告
  12. 分解GIF图片、合成GIF图片
  13. 计算机没有鼠标用英语怎么说,鼠标用英语怎么说
  14. 计算机的网络测速,网速知识 - 专业网速测试, 宽带提速, 游戏测速, 直播测速, 5G测速, 物联网监测 - SpeedTest.cn...
  15. C++ 全局变量 静态全局变量 傻傻分不清
  16. 保驾护航政务企业上云,云上安全一马当先
  17. lo linux 环回端口,本地环回接口lo The Loopback Network Interface lo--用Enki学Linux系列(2)...
  18. jdk常用工具命令总结
  19. 优麒麟 2204 安装 Fcitx5 输入法
  20. android 酷狗音乐 ip,“音乐+IP”融合模式 夯实酷狗音乐原创硬实力

热门文章

  1. Android模拟器学framework和driver之传感器篇1(linux sensor driver)
  2. 怎样提高WebService的性能
  3. html实时显示log,websocketd 实现浏览器查看服务器实时日志
  4. 《OpenCV3编程入门》学习笔记5 Core组件进阶(一)访问图像中的像素
  5. TensorFlow基本计算单元:代码示例
  6. mysql 主从 MySQLroute_mysql主从复制
  7. token验证失败_ASP.NET CORE WEBAPI JWT 带BEARER的TOKEN
  8. tensorboard merge报错_什么是TensorBoard?
  9. matlab在曲线给命名,matlab 利用xlsread画图,怎么将一组excel数据导入,通过matlab作图...
  10. linux路由内核实现分析 四,linux路由内核实现分析(二)---FIB相关数据结构(4)