mrneuralnet's picture
Initial commit
c0f8b72
raw
history blame contribute delete
No virus
5.73 kB
import sys, os
__dir__ = os.path.dirname(os.path.abspath(__file__))
sys.path.append(__dir__)
sys.path.append(os.path.abspath(os.path.join(__dir__, '..')))
import torch
import cv2
import numpy as np
from face_detection.data import cfg_mnet, cfg_re50
from face_detection.layers.functions.prior_box import PriorBox
from face_detection.utils.nms.py_cpu_nms import py_cpu_nms
from face_detection.models.retinaface import RetinaFace
from face_detection.utils.box_utils import decode
from face_detection.helper import remove_prefix, check_keys, get_boundingbox
class FaceDetection:
def __init__(self, batch_size=16, device=None, gpu_id=0, weights='./weights/Resnet50_Final.pth'):
torch.backends.cudnn.benchmark = True
if device:
self.device = device
elif torch.cuda.is_available() and gpu_id != -1:
self.device = 'cuda:{}'.format(gpu_id)
else:
self.device = 'cpu'
self.device = torch.device(self.device)
self.batch_size = batch_size
self.load_model(weights, self.device, load_to_cpu=True if str(self.device)=='cpu' else False)
self.model.eval()
def load_model(self, pretrained_path, device, load_to_cpu=False):
print('Loading pretrained model from {}'.format(pretrained_path))
if load_to_cpu:
pretrained_dict = torch.load(
pretrained_path, map_location=lambda storage, loc: storage)
else:
pretrained_dict = torch.load(
pretrained_path, map_location=lambda storage, loc: storage.cuda(device))
if "state_dict" in pretrained_dict.keys():
pretrained_dict = remove_prefix(
pretrained_dict['state_dict'], 'module.')
else:
pretrained_dict = remove_prefix(pretrained_dict, 'module.')
self.model = RetinaFace(cfg=cfg_re50, phase='test')
check_keys(self.model, pretrained_dict)
self.model.load_state_dict(pretrained_dict, strict=False)
self.model.to(device)
def detect(self, images, model, device, resize=1, confidence_threshold=0.997):
"""
"And now I am become death, destroyer of worlds"
-The author who wrote this
"""
result = []
img_list = []
for img in images:
img = torch.tensor(img) - torch.tensor([104, 117, 123])
img_list.append(img)
im_height, im_width, _ = img_list[0].shape
scale = torch.Tensor([im_width, im_height, im_width, im_height])
img_x = torch.stack(img_list, dim=0).permute([0, 3, 1, 2])
scale = scale.to(device)
# forward times
f_times = img_x.shape[0] // self.batch_size
if img_x.shape[0] % self.batch_size != 0:
f_times += 1
locs_list = list()
confs_list = list()
with torch.no_grad():
for _ in range(f_times):
if _ != f_times - 1:
batch_img_x = img_x[_ * self.batch_size:(_ + 1) * self.batch_size]
else:
batch_img_x = img_x[_ * self.batch_size:] # last batch
batch_img_x = batch_img_x.to(device).float()
l, c, _ = model(batch_img_x)
locs_list.append(l)
confs_list.append(c)
locs = torch.cat(locs_list, dim=0)
confs = torch.cat(confs_list, dim=0)
priorbox = PriorBox(cfg_re50, image_size=(im_height, im_width))
priors = priorbox.forward()
priors = priors.to(device)
prior_data = priors.data
img_cpu = img_x.permute([0, 2, 3, 1]).cpu().numpy()
i = 0
for img, loc, conf in zip(img_cpu, locs, confs):
boxes = decode(loc.data, prior_data, cfg_re50['variance'])
boxes = boxes * scale / resize
boxes = boxes.cpu().numpy()
scores = conf.data.cpu().numpy()[:, 1]
# ignore low scores
inds = np.where(scores > confidence_threshold)[0]
boxes = boxes[inds]
scores = scores[inds]
# keep top-K before NMS
order = scores.argsort()[::-1][:] # top_k
boxes = boxes[order]
scores = scores[order]
# do NMS
dets = np.hstack((boxes, scores[:, np.newaxis])).astype(
np.float32, copy=False)
keep = py_cpu_nms(dets, 0.4) # nms threshold
dets = dets[keep, :]
# keep top-K faster NMS
dets = dets[:, :] # keep top k
if len(dets) == 0:
continue
face_images = []
face_bbox = []
for det in dets:
det = list(map(int, det))
x, y, size_bb_x, size_bb_y = get_boundingbox(det, img.shape[1], img.shape[0])
cropped_img = img[y:y + size_bb_y, x:x + size_bb_x, :] + (104, 117, 123)
cropped_img = cropped_img.astype(np.uint8)
face_images.append(cropped_img)
face_bbox.append({
'top':y,
'left':x,
'width': size_bb_x,
'height':size_bb_y,
})
i += 1
result.append({'face_images': face_images,
'face_bbox': face_bbox})
return result
def __call__(self, images, confidence_threshold=0.997, return_heatmap=False):
return self.detect(images, confidence_threshold=confidence_threshold, model=self.model, device=self.device)
if __name__ == '__main__':
img = cv2.imread('sample_files/wefie.jpg')
face_detector = FaceDetection()
result = face_detector([img])
print(result)