python实现单目标、多目标、多尺度、自定义特征的KCF跟踪算法(实例代码)


Posted in Python onJanuary 08, 2020

单目标跟踪:

直接调用opencv中封装的tracker即可。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Jan 5 17:50:47 2020
第四章 kcf跟踪
@author: youxinlin
"""
import cv2
from items import MessageItem
import time
import numpy as np
'''
监视者模块,负责入侵检测,目标跟踪
'''
class WatchDog(object):
 #入侵检测者模块,用于入侵检测
 def __init__(self,frame=None):
  #运动检测器构造函数
  self._background = None
  if frame is not None:
   self._background = cv2.GaussianBlur(cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY),(21,21),0)
  self.es = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (10, 10))
 def isWorking(self):
  #运动检测器是否工作
  return self._background is not None
 def startWorking(self,frame):
  #运动检测器开始工作
  if frame is not None:
   self._background = cv2.GaussianBlur(cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY), (21, 21), 0)
 def stopWorking(self):
  #运动检测器结束工作
  self._background = None
 def analyze(self,frame):
  #运动检测
  if frame is None or self._background is None:
   return
  sample_frame = cv2.GaussianBlur(cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY),(21,21),0)
  diff = cv2.absdiff(self._background,sample_frame)
  diff = cv2.threshold(diff, 25, 255, cv2.THRESH_BINARY)[1]
  diff = cv2.dilate(diff, self.es, iterations=2)
  image, cnts, hierarchy = cv2.findContours(diff.copy(),cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  coordinate = []
  bigC = None
  bigMulti = 0
  for c in cnts:
   if cv2.contourArea(c) < 1500:
    continue
   (x,y,w,h) = cv2.boundingRect(c)
   if w * h > bigMulti:
    bigMulti = w * h
    bigC = ((x,y),(x+w,y+h))
  if bigC:
   cv2.rectangle(frame, bigC[0],bigC[1], (255,0,0), 2, 1)
  coordinate.append(bigC)
  message = {"coord":coordinate}
  message['msg'] = None
  return MessageItem(frame,message)
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_create(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:
     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"
  return MessageItem(frame,message)
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),(0,0,255),2)
  return frame
if __name__ == '__main__' :
# tracker_types = ['BOOSTING', 'MIL','KCF', 'TLD', 'MEDIANFLOW', 'GOTURN']
 tracker = Tracker(tracker_type="KCF")
# video = cv2.VideoCapture(0)
# video = cv2.VideoCapture("complex1.mov")
 video = cv2.VideoCapture(r"/Users/youxinlin/Desktop/video_data/complex1.MOV") 
 ok, frame = video.read()
 bbox = cv2.selectROI(frame, False)
 tracker.initWorking(frame,bbox)
 while True:
  _,frame = video.read();
  if(_):
   item = tracker.track(frame);
   cv2.imshow("track",item.getFrame())
   k = cv2.waitKey(1) & 0xff
   if k == 27:
    break

附带items.py,放在同个文件夹下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Jan 5 17:51:04 2020
@author: youxinlin
"""
import json
from utils import IOUtil
'''
信息封装类
'''
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])

utils.py:也放在同一个文件夹下。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Jan 5 17:51:40 2020
@author: youxinlin
"""
import time
import numpy
import base64
import os
import logging
import sys
from PIL import Image
from io import BytesIO
#工具类
class IOUtil(object):
 #流操作工具类
 @staticmethod
 def array_to_bytes(pic,formatter="jpeg",quality=70):
  '''
  静态方法,将numpy数组转化二进制流
  :param pic: numpy数组
  :param format: 图片格式
  :param quality:压缩比,压缩比越高,产生的二进制数据越短
  :return: 
  '''
  stream = BytesIO()
  picture = Image.fromarray(pic)
  picture.save(stream,format=formatter,quality=quality)
  jepg = stream.getvalue()
  stream.close()
  return jepg
 @staticmethod
 def bytes_to_base64(byte):
  '''
  静态方法,bytes转base64编码
  :param byte: 
  :return: 
  '''
  return base64.b64encode(byte)
 @staticmethod
 def transport_rgb(frame):
  '''
  将bgr图像转化为rgb图像,或者将rgb图像转化为bgr图像
  '''
  return frame[...,::-1]
 @staticmethod
 def byte_to_package(bytes,cmd,var=1):
  '''
  将每一帧的图片流的二进制数据进行分包
  :param byte: 二进制文件
  :param cmd:命令
  :return: 
  '''
  head = [ver,len(byte),cmd]
  headPack = struct.pack("!3I", *head)
  senddata = headPack+byte
  return senddata
 @staticmethod
 def mkdir(filePath):
  '''
  创建文件夹
  '''
  if not os.path.exists(filePath):
   os.mkdir(filePath)
 @staticmethod
 def countCenter(box):
  '''
  计算一个矩形的中心
  '''
  return (int(abs(box[0][0] - box[1][0])*0.5) + box[0][0],int(abs(box[0][1] - box[1][1])*0.5) +box[0][1])
 @staticmethod
 def countBox(center):
  '''
  根据两个点计算出,x,y,c,r
  '''
  return (center[0][0],center[0][1],center[1][0]-center[0][0],center[1][1]-center[0][1])
 @staticmethod
 def getImageFileName():
  return time.strftime("%Y_%m_%d_%H_%M_%S", time.localtime())+'.png'

多目标跟踪:

和单目标差不多,改用MultiTracker_create()

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Jan 5 18:02:33 2020

目标跟踪

@author: youxinlin
"""import numpy as np
import cv2
import sys
'''
if len(sys.argv) != 2:
 print('Input video name is missing')
 exit()
'''
print('Select multiple tracking targets') 
cv2.namedWindow("tracking")
camera = cv2.VideoCapture(r"/Users/youxinlin/Desktop/video_data/complex6.MOV") 
#camera = cv2.VideoCapture(0)
tracker = cv2.MultiTracker_create() #多目标跟踪
a= cv2.Tracker_c
init_once = False
ok, image=camera.read()
if not ok:
 print('Failed to read video')
 exit()
bbox1 = cv2.selectROI('tracking', image)
bbox2 = cv2.selectROI('tracking', image)
bbox3 = cv2.selectROI('tracking', image)
while camera.isOpened():
 ok, image=camera.read()
 if not ok:
  print ('no image to read')
  break
 if not init_once:
  ok = tracker.add(cv2.TrackerKCF_create(),image,bbox1)
  ok = tracker.add(cv2.TrackerKCF_create( ),image, bbox2)
  ok = tracker.add(cv2.TrackerKCF_create(),image, bbox3)
  init_once = True
 ok, boxes = tracker.update(image)
 for newbox in boxes:
  p1 = (int(newbox[0]), int(newbox[1]))
  p2 = (int(newbox[0] + newbox[2]), int(newbox[1] + newbox[3]))
  cv2.rectangle(image, p1, p2, (0,0,255))
 cv2.imshow('tracking', image)
 k = cv2.waitKey(1)
 if k == 27 : break # esc pressed

多尺度检测的KCF、自定义所用特征的KCF

在一些场景下,不想使用默认的hog特征跟踪,或需要对比不同特征的跟踪效果,那么封装好的方法似乎不可用,需要可以自己撸一波kcf的代码,从而使用自己设定的特征。

总结

以上所述是小编给大家介绍的python实现单目标、多目标、多尺度、自定义特征的KCF跟踪算法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
Python深入学习之对象的属性
Aug 31 Python
连接Python程序与MySQL的教程
Apr 29 Python
从Python的源码来解析Python下的freeblock
May 11 Python
python做量化投资系列之比特币初始配置
Jan 23 Python
python使用插值法画出平滑曲线
Dec 15 Python
Pycharm配置远程调试的方法步骤
Dec 17 Python
python实现网页自动签到功能
Jan 21 Python
python循环定时中断执行某一段程序的实例
Jun 29 Python
python fuzzywuzzy模块模糊字符串匹配详细用法
Aug 29 Python
Python常用模块sys,os,time,random功能与用法实例分析
Jan 07 Python
python颜色随机生成器的实例代码
Jan 10 Python
Python实现实时数据采集新型冠状病毒数据实例
Feb 04 Python
Pytorch实现神经网络的分类方式
Jan 08 #Python
python 爬取古诗文存入mysql数据库的方法
Jan 08 #Python
基于python3抓取pinpoint应用信息入库
Jan 08 #Python
Python PyInstaller安装和使用教程详解
Jan 08 #Python
关于Pytorch的MLP模块实现方式
Jan 07 #Python
PyTorch 普通卷积和空洞卷积实例
Jan 07 #Python
Pytorch中膨胀卷积的用法详解
Jan 07 #Python
You might like
详解 PHP加密解密字符串函数附源码下载
2015/12/18 PHP
PHP图片加水印实现方法
2016/05/06 PHP
PHP实现在数据库百万条数据中随机获取20条记录的方法
2017/04/19 PHP
PHP实现QQ、微信和支付宝三合一收款码实例代码
2018/02/19 PHP
JavaScript 学习笔记 Black.Caffeine 09.11.28
2009/11/30 Javascript
jquery插件之定时查询待处理任务数量
2014/05/01 Javascript
js判断游览器类型及版本号的代码
2014/05/11 Javascript
如何在MVC应用程序中使用Jquery
2014/11/17 Javascript
javascript实现倒计时N秒后网页自动跳转代码
2014/12/11 Javascript
jquery实现用户信息修改验证输入方法汇总
2015/07/18 Javascript
轻量级javascript 框架Backbone使用指南
2015/07/24 Javascript
JavaScript 不支持 indexof 该如何解决
2016/03/30 Javascript
JQuery Mobile 弹出式登录框的实现方法
2016/05/28 Javascript
jQ处理xml文件和xml字符串的方法(详解)
2016/11/22 Javascript
Node.js使用NodeMailer发送邮件实例代码
2017/03/06 Javascript
基于bootstrop常用类总结(推荐)
2017/09/11 Javascript
在Node.js下运用MQTT协议实现即时通讯及离线推送的方法
2019/01/24 Javascript
python基础教程之popen函数操作其它程序的输入和输出示例
2014/02/10 Python
Python编程中的反模式实例分析
2014/12/08 Python
简单介绍Python的轻便web框架Bottle
2015/04/08 Python
python爬虫入门教程--利用requests构建知乎API(三)
2017/05/25 Python
python用fsolve、leastsq对非线性方程组求解
2018/12/15 Python
Python自动化之数据驱动让你的脚本简洁10倍【推荐】
2019/06/04 Python
pytorch 改变tensor尺寸的实现
2020/01/03 Python
如何在 Django 模板中输出 &quot;{{&quot;
2020/01/24 Python
Python实现检测文件的MD5值来查找重复文件案例
2020/03/12 Python
孕妇内衣和胸罩:Cake Maternity
2018/07/16 全球购物
俄罗斯名牌服装网上商店:UNIQUE FABRIC
2019/07/25 全球购物
Java中会存在内存泄漏吗,请简单描述
2016/12/22 面试题
UNIX文件系统常用命令
2012/05/25 面试题
石油工程专业毕业生求职信
2014/04/13 职场文书
工作作风整顿个人剖析材料
2014/10/11 职场文书
2016年情人节问候语
2015/11/11 职场文书
解决persistence.xml配置文件修改存放路径的问题
2022/02/24 Java/Android
Python Matplotlib绘制两个Y轴图像
2022/04/13 Python
python数字图像处理之对比度与亮度调整示例
2022/06/28 Python