deepsafe's picture
Add stripped inference-only model code mirror
9e14838 verified
Raw History Blame Contribute Delete
4.39 kB
import cv2
# from test_tools.utils import flatten
import numpy as np
def flatten(l):
return [item for sublist in l for item in sublist]
def chunks(l, n, step=None):
if step is None:
step = n
return [l[i : i + n] for i in range(0, len(l), step)]
def sample_chunks(l, n, step=None):
return [l[i : i + n] for i in range(0, len(l), step) if i + n <= len(l)]
def grab_all_frames(path, max_size, cvt=False):
capture = cv2.VideoCapture(path)
ret = True
frames = []
while ret:
ret, frame = capture.read()
if ret:
if cvt:
frame = frame[..., ::-1]
frames.append(frame)
if len(frames) == max_size:
break
capture.release()
return frames
def get_clips_uniform(path, count, clip_size):
capture = cv2.VideoCapture(path)
n_frames = int(capture.get(cv2.CAP_PROP_FRAME_COUNT))
max_clip_available = n_frames + 1 - clip_size
if count > max_clip_available:
count = max_clip_available
final_start = max_clip_available - 1
start_indices = np.linspace(0, final_start, count, endpoint=True, dtype=np.int)
all_clip_idx = [list(range(start, start + clip_size)) for start in start_indices]
valid = set(flatten(all_clip_idx))
max_idx = max(valid)
frames = {}
for idx in range(max_idx + 1):
# Get the next frame, but don't decode if we're not using it.
ret = capture.grab()
if not ret:
continue
if idx in valid:
ret, frame = capture.retrieve()
if not ret or frame is None:
continue
else:
# frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frames[idx] = frame
capture.release()
clips = []
for clip_idx in all_clip_idx:
clip = []
flag = True
for idx in clip_idx:
if idx not in frames:
flag = False
break
clip.append(frames[idx])
if flag:
clips.append(clip)
return clips
def get_valid_faces(detect_results, max_count=10, thres=0.5, at_least=False):
new_results = []
for i, faces in enumerate(detect_results):
if len(faces) > max_count:
faces = faces[:max_count]
l = []
for j, face in enumerate(faces):
if face[-1] < thres and not (j == 0 and at_least):
continue
box, lm, score = face
box = box.astype(np.float64)
lm = lm.astype(np.float64)
l.append((box, lm, score))
new_results.append(l)
return new_results
def scale_box(box, scale_h, scale_w, h, w):
x1, y1, x2, y2 = box.astype(np.int32)
center_x = (x1 + x2) // 2
center_y = (y1 + y2) // 2
box_h = int((y2 - y1) * scale_h)
box_w = int((x2 - x1) * scale_w)
new_x1 = center_x - box_w // 2
new_x2 = new_x1 + box_w
new_y1 = center_y - box_h // 2
new_y2 = new_y1 + box_h
new_x1 = max(new_x1, 0)
new_y1 = max(new_y1, 0)
new_y2 = min(new_y2, h)
new_x2 = min(new_x2, w)
return new_x1, new_y1, new_x2, new_y2
def get_bbox(detect_res):
tmp_detect_res = get_valid_faces(detect_res, max_count=4, thres=0.5)
all_face_bboxs = []
for faces in tmp_detect_res:
all_face_bboxs.extend([face[0] for face in faces])
all_face_bboxs = np.array(all_face_bboxs).astype(np.int)
x1 = all_face_bboxs[:, 0].min()
x2 = all_face_bboxs[:, 2].max()
y1 = all_face_bboxs[:, 1].min()
y2 = all_face_bboxs[:, 3].max()
return x1, y1, x2, y2
def delta_detect_res(detect_res, x1, y1):
diff = np.array([[x1, y1]])
new_detect_res = []
for faces in detect_res:
f = []
for face in faces:
box, lm, score = face
box = box.astype(np.float64)
box[[0, 2]] -= x1
box[[1, 3]] -= y1
lm = lm.astype(np.float64) - diff
f.append((box, lm, score))
new_detect_res.append(f)
return new_detect_res
def pre_crop(clips, detect_res):
box = np.array(get_bbox(detect_res))
w = box[2] - box[0]
h = box[3] - box[1]
x1, y1, x2, y2 = scale_box(
box, 1.5, 1.2 if w > 2 * h else 1.5, clips[0].shape[0], clips[0].shape[1]
)
clips = np.array(clips)
return clips[:, y1:y2, x1:x2], delta_detect_res(detect_res, x1, y1)