python+opencv实现目标跟踪过程


Posted in Python onJune 21, 2022

python opencv实现目标跟踪

python-opencv3.0新增了一些比较有用的追踪器算法

这里根据官网示例写了一个追踪器类

程序只能运行在安装有opencv3.0以上版本和对应的contrib模块的python解释器

#encoding=utf-8
 
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),(255,0,0),2)
        return frame
 
if __name__ == '__main__' :
    a = ['BOOSTING', 'MIL','KCF', 'TLD', 'MEDIANFLOW', 'GOTURN']
    tracker = Tracker(tracker_type="KCF")
    video = cv2.VideoCapture(0)
    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
#encoding=utf-8
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])

运行之后在第一帧图像上选择要追踪的部分,这里测试了一下使用KCF算法的追踪器

python+opencv实现目标跟踪过程

更新:忘记放utils,给大家造成的困扰深表歉意

#encoding=utf-8
import time
import numpy
import base64
import os
import logging
import sys
from settings import *
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'
 
#构造日志
logger = logging.getLogger(LOG_NAME)
formatter = logging.Formatter(LOG_FORMATTER)
IOUtil.mkdir(LOG_DIR);
file_handler = logging.FileHandler(LOG_DIR + LOG_FILE,encoding='utf-8')
file_handler.setFormatter(formatter)
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.addHandler(console_handler)
logger.setLevel(logging.INFO)

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。


Tags in this post...

Python 相关文章推荐
python实现批量改文件名称的方法
May 25 Python
Flask框架的学习指南之开发环境搭建
Nov 20 Python
Pandas探索之高性能函数eval和query解析
Oct 28 Python
利用Pandas 创建空的DataFrame方法
Apr 08 Python
Python多进程池 multiprocessing Pool用法示例
Sep 07 Python
python实现汽车管理系统
Nov 30 Python
远程部署工具Fabric详解(支持Python3)
Jul 04 Python
python的一些加密方法及python 加密模块
Jul 11 Python
Python+Tensorflow+CNN实现车牌识别的示例代码
Oct 11 Python
用Python实现定时备份Mongodb数据并上传到FTP服务器
Jan 27 Python
matplotlib源码解析标题实现(窗口标题,标题,子图标题不同之间的差异)
Feb 22 Python
python opencv将多个图放在一个窗口的实例详解
Feb 28 Python
使用opencv-python如何打开USB或者笔记本前置摄像头
Python+DeOldify实现老照片上色功能
Python使用Opencv打开笔记本电脑摄像头报错解问题及解决
Jun 21 #Python
virtualenv隔离Python环境的问题解析
Jun 21 #Python
pd.drop_duplicates删除重复行的方法实现
Jun 16 #Python
使用pd.merge表连接出现多余行的问题解决
Jun 16 #Python
pd.DataFrame中的几种索引变换的实现
You might like
PHP的异常处理类Exception的使用及说明
2012/06/13 PHP
了解PHP的返回引用和局部静态变量
2015/06/04 PHP
PHP实现的最大正向匹配算法示例
2017/12/19 PHP
javascript图像处理—仿射变换深度理解
2013/01/16 Javascript
JS保留两位小数 四舍五入函数的小例子
2013/11/20 Javascript
httpclient模拟登陆具体实现(使用js设置cookie)
2013/12/11 Javascript
Jquery promise实现一张一张加载图片
2015/11/13 Javascript
JavaScript中的Reflect对象详解(ES6新特性)
2016/07/22 Javascript
AngularJS ng-app 指令实例详解
2016/07/30 Javascript
利用jQuery实现打字机字幕效果实例代码
2016/09/02 Javascript
jQuery设置和获取select、checkbox、radio的选中值方法
2017/01/01 Javascript
vue中将网页打印成pdf实例代码
2017/06/15 Javascript
Vue数据双向绑定原理及简单实现方法
2018/05/18 Javascript
vue中的数据绑定原理的实现
2018/07/02 Javascript
JavaScript引用类型Date常见用法实例分析
2018/08/08 Javascript
vue实现一个炫酷的日历组件
2018/10/08 Javascript
使用layui实现的左侧菜单栏以及动态操作tab项方法
2019/09/10 Javascript
vue3.0 的 Composition API 的使用示例
2020/10/26 Javascript
Python 常用 PEP8 编码规范详解
2017/01/22 Python
对Python信号处理模块signal详解
2019/01/09 Python
详解Python 定时框架 Apscheduler原理及安装过程
2019/06/14 Python
使用python matplotlib 画图导入到word中如何保证分辨率
2020/04/16 Python
Python HTMLTestRunner库安装过程解析
2020/05/25 Python
Python 爬虫性能相关总结
2020/08/03 Python
Python使用Selenium模拟浏览器自动操作功能
2020/09/08 Python
python爬虫判断招聘信息是否存在的实例代码
2020/11/20 Python
CSS3 calc()会计算属性详解
2018/02/27 HTML / CSS
Top Villas美国:豪华别墅出租和度假屋
2018/07/10 全球购物
采购主管工作职责
2013/12/12 职场文书
小学学习雷锋活动总结
2014/07/03 职场文书
工伤死亡理赔协议书
2014/10/20 职场文书
资产移交协议书
2016/03/24 职场文书
js实现模拟购物商城案例
2021/05/18 Javascript
详解PHP Swoole与TCP三次握手
2021/05/27 PHP
spring IOC容器的Bean管理XML自动装配过程
2022/05/30 Java/Android
Redis全局ID生成器的实现
2022/06/05 Redis