akhaliq's picture
akhaliq HF staff
add files
64dbbc4
import time
import cv2
import numpy as np
from .config import config as cfg
from .face_detector import FaceDetector
from .face_landmark import FaceLandmark
from .LK.lk import GroupTrack
class FaceAna():
'''
by default the top3 facea sorted by area will be calculated for time reason
'''
def __init__(self, model_dir):
self.face_detector = FaceDetector(model_dir)
self.face_landmark = FaceLandmark(model_dir)
self.trace = GroupTrack()
self.track_box = None
self.previous_image = None
self.previous_box = None
self.diff_thres = 5
self.top_k = cfg.DETECT.topk
self.iou_thres = cfg.TRACE.iou_thres
self.alpha = cfg.TRACE.smooth_box
def run(self, image):
boxes = self.face_detector(image)
if boxes.shape[0] > self.top_k:
boxes = self.sort(boxes)
boxes_return = np.array(boxes)
landmarks, states = self.face_landmark(image, boxes)
if 1:
track = []
for i in range(landmarks.shape[0]):
track.append([
np.min(landmarks[i][:, 0]),
np.min(landmarks[i][:, 1]),
np.max(landmarks[i][:, 0]),
np.max(landmarks[i][:, 1])
])
tmp_box = np.array(track)
self.track_box = self.judge_boxs(boxes_return, tmp_box)
self.track_box, landmarks = self.sort_res(self.track_box, landmarks)
return self.track_box, landmarks, states
def sort_res(self, bboxes, points):
area = []
for bbox in bboxes:
bbox_width = bbox[2] - bbox[0]
bbox_height = bbox[3] - bbox[1]
area.append(bbox_height * bbox_width)
area = np.array(area)
picked = area.argsort()[::-1]
sorted_bboxes = [bboxes[x] for x in picked]
sorted_points = [points[x] for x in picked]
return np.array(sorted_bboxes), np.array(sorted_points)
def diff_frames(self, previous_frame, image):
if previous_frame is None:
return True
else:
_diff = cv2.absdiff(previous_frame, image)
diff = np.sum(
_diff) / previous_frame.shape[0] / previous_frame.shape[1] / 3.
return diff > self.diff_thres
def sort(self, bboxes):
if self.top_k > 100:
return bboxes
area = []
for bbox in bboxes:
bbox_width = bbox[2] - bbox[0]
bbox_height = bbox[3] - bbox[1]
area.append(bbox_height * bbox_width)
area = np.array(area)
picked = area.argsort()[-self.top_k:][::-1]
sorted_bboxes = [bboxes[x] for x in picked]
return np.array(sorted_bboxes)
def judge_boxs(self, previuous_bboxs, now_bboxs):
def iou(rec1, rec2):
# computing area of each rectangles
S_rec1 = (rec1[2] - rec1[0]) * (rec1[3] - rec1[1])
S_rec2 = (rec2[2] - rec2[0]) * (rec2[3] - rec2[1])
# computing the sum_area
sum_area = S_rec1 + S_rec2
# find the each edge of intersect rectangle
x1 = max(rec1[0], rec2[0])
y1 = max(rec1[1], rec2[1])
x2 = min(rec1[2], rec2[2])
y2 = min(rec1[3], rec2[3])
# judge if there is an intersect
intersect = max(0, x2 - x1) * max(0, y2 - y1)
return intersect / (sum_area - intersect)
if previuous_bboxs is None:
return now_bboxs
result = []
for i in range(now_bboxs.shape[0]):
contain = False
for j in range(previuous_bboxs.shape[0]):
if iou(now_bboxs[i], previuous_bboxs[j]) > self.iou_thres:
result.append(
self.smooth(now_bboxs[i], previuous_bboxs[j]))
contain = True
break
if not contain:
result.append(now_bboxs[i])
return np.array(result)
def smooth(self, now_box, previous_box):
return self.do_moving_average(now_box[:4], previous_box[:4])
def do_moving_average(self, p_now, p_previous):
p = self.alpha * p_now + (1 - self.alpha) * p_previous
return p
def reset(self):
'''
reset the previous info used foe tracking,
:return:
'''
self.track_box = None
self.previous_image = None
self.previous_box = None