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在linux中输出带颜色的文字的方法
Jun 19 Python
python基础教程之对象和类的实际运用
Aug 29 Python
python使用datetime模块计算各种时间间隔的方法
Mar 24 Python
Python脚本在Appium库上对移动应用实现自动化测试
Apr 17 Python
对Python字符串中的换行符和制表符介绍
May 03 Python
python实现定时提取实时日志程序
Jun 22 Python
浅谈django rest jwt vue 跨域问题
Oct 26 Python
python 实现语音聊天机器人的示例代码
Dec 02 Python
python将控制台输出保存至文件的方法
Jan 07 Python
Python实现栈的方法详解【基于数组和单链表两种方法】
Feb 22 Python
django模型类中,null=True,blank=True用法说明
Jul 09 Python
使用Python实现音频双通道分离
Dec 25 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中$GLOBALS['HTTP_RAW_POST_DATA']和$_POST的区别分析
2017/07/03 PHP
不安全的常用的js写法
2009/09/15 Javascript
JavaScript 学习初步 入门教程
2010/03/25 Javascript
浅析jQuery的链式调用之each函数
2010/12/03 Javascript
超酷的网页音乐播放器DewPlayer使用方法
2010/12/18 Javascript
JS中图片缓冲loading技术的实例代码
2013/08/29 Javascript
JavaScript获取对象在页面中位置坐标的方法
2016/02/03 Javascript
AngularJS基础 ng-copy 指令实例代码
2016/08/01 Javascript
jquery实现提示语淡入效果
2017/05/05 jQuery
JavaScript表单验证实现代码
2017/05/22 Javascript
初探JavaScript 面向对象(推荐)
2017/09/03 Javascript
SVG动画vivus.js库使用小结(实例代码)
2017/09/14 Javascript
详解node单线程实现高并发原理与node异步I/O
2017/09/21 Javascript
vue学习之mintui picker选择器实现省市二级联动示例
2017/10/12 Javascript
详解Vue2 SSR 缓存 Api 数据
2017/11/20 Javascript
微信小程序日期选择器实例代码
2018/07/18 Javascript
5分钟学会Vue动画效果(小结)
2018/07/21 Javascript
详解vue-property-decorator使用手册
2019/07/29 Javascript
[01:20]DOTA2 齐天大圣至宝动态展示
2016/12/13 DOTA
Python实现遍历windows所有窗口并输出窗口标题的方法
2015/03/13 Python
Python探索之创建二叉树
2017/10/25 Python
Python中return self的用法详解
2018/07/27 Python
python用线性回归预测股票价格的实现代码
2019/09/04 Python
python实现操作文件(文件夹)
2019/10/31 Python
Oakley官网:运动太阳镜、雪镜和服装
2016/09/30 全球购物
英国最大的电子零件及配件零售商:Partmaster
2017/04/24 全球购物
Bibloo荷兰:女士、男士和儿童的服装、鞋子和配饰
2019/02/25 全球购物
意大利买卖二手奢侈品网站:LAMPOO
2020/06/03 全球购物
Nobody Denim官网:购买高级女士牛仔裤
2021/03/15 全球购物
优秀公益广告词大全
2014/03/19 职场文书
小学生放飞梦想演讲稿
2014/08/26 职场文书
2016教师读书思廉心得体会
2016/01/23 职场文书
Sql-Server数据库单表查询 4.3实验课
2021/04/05 SQL Server
python 用递归实现通用爬虫解析器
2021/04/16 Python
Python实现批量自动整理文件
2022/03/16 Python
进阶篇之linux环境下安装MySQL数据库
2022/04/09 MySQL