双向队列 deque
跟踪算法中需要记录前后多帧的数据,使用一个双向队列deque
,来自于包collection
,deque类源码如下:
class deque(MutableSequence[_T], Generic[_T]):
@property
def maxlen(self) -> int | None: ...
@overload
def __init__(self, *, maxlen: int | None = ...) -> None: ...
@overload
def __init__(self, iterable: Iterable[_T], maxlen: int | None = ...) -> None: ...
def append(self, __x: _T) -> None: ...
def appendleft(self, __x: _T) -> None: ...
def copy(self: Self) -> Self: ...
def count(self, __x: _T) -> int: ...
def extend(self, __iterable: Iterable[_T]) -> None: ...
def extendleft(self, __iterable: Iterable[_T]) -> None: ...
def insert(self, __i: int, __x: _T) -> None: ...
def index(self, __x: _T, __start: int = ..., __stop: int = ...) -> int: ...
def pop(self) -> _T: ... # type: ignore[override]
def popleft(self) -> _T: ...
def remove(self, __value: _T) -> None: ...
def rotate(self, __n: int = ...) -> None: ...
...
使用方法如下:
from collections import deque
data_deque = deque(maxlen = 64 )
data_deque.appendleft(xxx)
这样,一个长度为64的双向队列就可以使用了,data_deque的最大长度会维持在64,对于我们一般的模型,如果帧率是30,那么这个队列长度可以保留大概2秒多的数据,相当于有2秒的记忆,在跟踪模型中,这个类很有用
四点相交判定方法 intersect
对于跟踪模型除了需要判定目标是否在某一区域中,有时候还需要判定目标轨迹是否跨越边界线,这时候,需要一个数学算法,根据轨迹点以及边界点连线,判定四点是否相交,方法如下:
def intersect(A,B,C,D):
return ccw(A,C,D) != ccw(B,C,D) and ccw(A,B,C) != ccw(A,B,D)
def ccw(A,B,C):
return (C[1]-A[1]) * (B[0]-A[0]) > (B[1]-A[1]) * (C[0]-A[0])
轨迹方向判定 get_direction
对于轨迹方向,这里只给出两点坐标计算的方向,为了直观,我们以画面上北下南左西右东表示方向,实际可灵活使用,做相应映射即可,方法如下:
def get_direction(point1, point2):
direction_str = ""
# calculate y axis direction
if point1[1] > point2[1]:
direction_str += "South"
elif point1[1] < point2[1]:
direction_str += "North"
else:
direction_str += ""
# calculate x axis direction
if point1[0] > point2[0]:
direction_str += "East"
elif point1[0] < point2[0]:
direction_str += "West"
else:
direction_str += ""
日志模块 logging
在项目中,日志非常重要,logging模块功能完善,可以实现不同级别的日志输出,并且可指定分割,下面简要介绍方法。
step1: 导入模块
import logging
from logging.handlers import TimedRotatingFileHandler
这里我们用到了TimedRotatingFileHandler
,此方法专门解决关于时间的日志处理
step2: 初始化
# 分两小块,一是初始化时间分块相关参数,下面的timefilehandler就指定了每隔1小时备份一次,最大备份数量1000个,编码指定为utf8,更加通用
timefilehandler = TimedRotatingFileHandler(
filename="./logs/sendReport.log",
when='H',
interval=1,
backupCount=1000,
encoding="utf8"
)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
timefilehandler.suffix = "-%Y-%m-%d_%H_%M_%S.log"
timefilehandler.setFormatter(formatter)
#第二块是初始化logger对象,并指定级别和设定参数
loggerV2 = logging.getLogger('sendLog')
loggerV2.setLevel(logging.INFO)
loggerV2.addHandler(timefilehandler)
#使用
loggerV2.info("{}".format(str(data)))
更多功能请参加官方文档。