| from .detector import Detector |
| import cv2, os |
| import numpy as np |
| import torch |
| import torch.nn as nn |
| from .utils.config import cfg |
| from .utils.prior_box import PriorBox |
| from .utils.nms_wrapper import nms |
| from .utils.faceboxes import FaceBoxesV2 |
| from .utils.box_utils import decode |
| import time |
|
|
| class FaceBoxesDetector(Detector): |
| def __init__(self, model_arch, model_weights, use_gpu, device): |
| super().__init__(model_arch, model_weights) |
| self.name = 'FaceBoxesDetector' |
| self.net = FaceBoxesV2(phase='test', size=None, num_classes=2) |
| self.use_gpu = use_gpu |
| self.device = device |
|
|
| state_dict = torch.load(self.model_weights, map_location=self.device) |
| |
| from collections import OrderedDict |
| new_state_dict = OrderedDict() |
| for k, v in state_dict.items(): |
| name = k[7:] |
| new_state_dict[name] = v |
| |
| self.net.load_state_dict(new_state_dict) |
| self.net = self.net.to(self.device) |
| self.net.eval() |
|
|
|
|
| def detect(self, image, thresh=0.6, im_scale=None): |
| |
| if im_scale is None: |
| height, width, _ = image.shape |
| if min(height, width) > 600: |
| im_scale = 600. / min(height, width) |
| else: |
| im_scale = 1 |
| image_scale = cv2.resize(image, None, None, fx=im_scale, fy=im_scale, interpolation=cv2.INTER_LINEAR) |
|
|
| scale = torch.Tensor([image_scale.shape[1], image_scale.shape[0], image_scale.shape[1], image_scale.shape[0]]) |
| image_scale = torch.from_numpy(image_scale.transpose(2,0,1)).to(self.device).int() |
| mean_tmp = torch.IntTensor([104, 117, 123]).to(self.device) |
| mean_tmp = mean_tmp.unsqueeze(1).unsqueeze(2) |
| image_scale -= mean_tmp |
| image_scale = image_scale.float().unsqueeze(0) |
| scale = scale.to(self.device) |
|
|
| with torch.no_grad(): |
| out = self.net(image_scale) |
| |
| priorbox = PriorBox(cfg, image_size=(image_scale.size()[2], image_scale.size()[3])) |
| priors = priorbox.forward() |
| priors = priors.to(self.device) |
| loc, conf = out |
| prior_data = priors.data |
| boxes = decode(loc.data.squeeze(0), prior_data, cfg['variance']) |
| boxes = boxes * scale |
| boxes = boxes.cpu().numpy() |
| scores = conf.data.cpu().numpy()[:, 1] |
|
|
| |
| inds = np.where(scores > thresh)[0] |
| boxes = boxes[inds] |
| scores = scores[inds] |
|
|
| |
| order = scores.argsort()[::-1][:5000] |
| boxes = boxes[order] |
| scores = scores[order] |
|
|
| |
| dets = np.hstack((boxes, scores[:, np.newaxis])).astype(np.float32, copy=False) |
| keep = nms(dets, 0.3) |
| dets = dets[keep, :] |
|
|
| dets = dets[:750, :] |
| detections_scale = [] |
| for i in range(dets.shape[0]): |
| xmin = int(dets[i][0]) |
| ymin = int(dets[i][1]) |
| xmax = int(dets[i][2]) |
| ymax = int(dets[i][3]) |
| score = dets[i][4] |
| width = xmax - xmin |
| height = ymax - ymin |
| detections_scale.append(['face', score, xmin, ymin, width, height]) |
|
|
| |
| if len(detections_scale) > 0: |
| detections_scale = [[det[0],det[1],int(det[2]/im_scale),int(det[3]/im_scale),int(det[4]/im_scale),int(det[5]/im_scale)] for det in detections_scale] |
|
|
| return detections_scale, im_scale |
|
|
|
|