diff --git a/.gitignore b/.gitignore index 350ada0..326fcd2 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,7 @@ Thumbs.db # Specific to this demo # ######################### data/ +output/ protos/ utils/ *.pth diff --git a/detectors/s3fd/box_utils.py b/detectors/s3fd/box_utils.py index 0779bcd..bcffcb7 100644 --- a/detectors/s3fd/box_utils.py +++ b/detectors/s3fd/box_utils.py @@ -35,7 +35,7 @@ def nms_(dets, thresh): inds = np.where(ovr <= thresh)[0] order = order[inds + 1] - return np.array(keep).astype(np.int) + return np.array(keep).astype(np.int32) def decode(loc, priors, variances): @@ -131,7 +131,7 @@ class Detect(object): def __init__(self, num_classes=2, top_k=750, nms_thresh=0.3, conf_thresh=0.05, variance=[0.1, 0.2], nms_top_k=5000): - + self.num_classes = num_classes self.top_k = top_k self.nms_thresh = nms_thresh @@ -160,7 +160,7 @@ def forward(self, loc_data, conf_data, prior_data): for cl in range(1, self.num_classes): c_mask = conf_scores[cl].gt(self.conf_thresh) scores = conf_scores[cl][c_mask] - + if scores.dim() == 0: continue l_mask = c_mask.unsqueeze(1).expand_as(boxes) @@ -210,8 +210,8 @@ def forward(self): mean += [cx, cy, s_kw, s_kh] output = torch.FloatTensor(mean).view(-1, 4) - + if self.clip: output.clamp_(max=1, min=0) - + return output diff --git a/run_pipeline.py b/run_pipeline.py index f5fc22e..ee4ead8 100755 --- a/run_pipeline.py +++ b/run_pipeline.py @@ -27,10 +27,10 @@ parser.add_argument('--reference', type=str, default='', help='Video reference'); parser.add_argument('--facedet_scale', type=float, default=0.25, help='Scale factor for face detection'); parser.add_argument('--crop_scale', type=float, default=0.40, help='Scale bounding box'); -parser.add_argument('--min_track', type=int, default=100, help='Minimum facetrack duration'); +parser.add_argument('--min_track', type=int, default=50, help='Minimum facetrack duration'); parser.add_argument('--frame_rate', type=int, default=25, help='Frame rate'); parser.add_argument('--num_failed_det', type=int, default=25, help='Number of missed detections allowed before tracking is stopped'); -parser.add_argument('--min_face_size', type=int, default=100, help='Minimum face size in pixels'); +parser.add_argument('--min_face_size', type=int, default=50, help='Minimum face size in pixels'); opt = parser.parse_args(); setattr(opt,'avi_dir',os.path.join(opt.data_dir,'pyavi')) @@ -44,19 +44,19 @@ # ========== ========== ========== ========== def bb_intersection_over_union(boxA, boxB): - + xA = max(boxA[0], boxB[0]) yA = max(boxA[1], boxB[1]) xB = min(boxA[2], boxB[2]) yB = min(boxA[3], boxB[3]) - + interArea = max(0, xB - xA) * max(0, yB - yA) - + boxAArea = (boxA[2] - boxA[0]) * (boxA[3] - boxA[1]) boxBArea = (boxB[2] - boxB[0]) * (boxB[3] - boxB[1]) - + iou = interArea / float(boxAArea + boxBArea - interArea) - + return iou # ========== ========== ========== ========== @@ -87,7 +87,7 @@ def track_shot(opt,scenefaces): if track == []: break elif len(track) > opt.min_track: - + framenum = np.array([ f['frame'] for f in track ]) bboxes = np.array([np.array(f['bbox']) for f in track]) @@ -107,7 +107,7 @@ def track_shot(opt,scenefaces): # ========== ========== ========== ========== # # VIDEO CROP AND SAVE # ========== ========== ========== ========== - + def crop_video(opt,track,cropfile): flist = glob.glob(os.path.join(opt.frames_dir,opt.reference,'*.jpg')) @@ -120,12 +120,12 @@ def crop_video(opt,track,cropfile): for det in track['bbox']: - dets['s'].append(max((det[3]-det[1]),(det[2]-det[0]))/2) - dets['y'].append((det[1]+det[3])/2) # crop center x + dets['s'].append(max((det[3]-det[1]),(det[2]-det[0]))/2) + dets['y'].append((det[1]+det[3])/2) # crop center x dets['x'].append((det[0]+det[2])/2) # crop center y # Smooth detections - dets['s'] = signal.medfilt(dets['s'],kernel_size=13) + dets['s'] = signal.medfilt(dets['s'],kernel_size=13) dets['x'] = signal.medfilt(dets['x'],kernel_size=13) dets['y'] = signal.medfilt(dets['y'],kernel_size=13) @@ -134,16 +134,16 @@ def crop_video(opt,track,cropfile): cs = opt.crop_scale bs = dets['s'][fidx] # Detection box size - bsi = int(bs*(1+2*cs)) # Pad videos by this amount + bsi = int(bs*(1+2*cs)) # Pad videos by this amount image = cv2.imread(flist[frame]) - + frame = np.pad(image,((bsi,bsi),(bsi,bsi),(0,0)), 'constant', constant_values=(110,110)) my = dets['y'][fidx]+bsi # BBox center Y mx = dets['x'][fidx]+bsi # BBox center X face = frame[int(my-bs):int(my+bs*(1+2*cs)),int(mx-bs*(1+cs)):int(mx+bs*(1+cs))] - + vOut.write(cv2.resize(face,(224,224))) audiotmp = os.path.join(opt.tmp_dir,opt.reference,'audio.wav') @@ -154,7 +154,7 @@ def crop_video(opt,track,cropfile): # ========== CROP AUDIO FILE ========== - command = ("ffmpeg -y -i %s -ss %.3f -to %.3f %s" % (os.path.join(opt.avi_dir,opt.reference,'audio.wav'),audiostart,audioend,audiotmp)) + command = ("ffmpeg -y -i %s -ss %.3f -to %.3f %s" % (os.path.join(opt.avi_dir,opt.reference,'audio.wav'),audiostart,audioend,audiotmp)) output = subprocess.call(command, shell=True, stdout=None) if output != 0: @@ -190,11 +190,11 @@ def inference_video(opt): flist.sort() dets = [] - + for fidx, fname in enumerate(flist): start_time = time.time() - + image = cv2.imread(fname) image_np = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) @@ -206,7 +206,7 @@ def inference_video(opt): elapsed_time = time.time() - start_time - print('%s-%05d; %d dets; %.2f Hz' % (os.path.join(opt.avi_dir,opt.reference,'video.avi'),fidx,len(dets[-1]),(1/elapsed_time))) + print('%s-%05d; %d dets; %.2f Hz' % (os.path.join(opt.avi_dir,opt.reference,'video.avi'),fidx,len(dets[-1]),(1/elapsed_time))) savepath = os.path.join(opt.work_dir,opt.reference,'faces.pckl') @@ -247,7 +247,7 @@ def scene_detect(opt): print('%s - scenes detected %d'%(os.path.join(opt.avi_dir,opt.reference,'video.avi'),len(scene_list))) return scene_list - + # ========== ========== ========== ========== # # EXECUTE DEMO @@ -283,10 +283,10 @@ def scene_detect(opt): command = ("ffmpeg -y -i %s -qscale:v 2 -async 1 -r 25 %s" % (opt.videofile,os.path.join(opt.avi_dir,opt.reference,'video.avi'))) output = subprocess.call(command, shell=True, stdout=None) -command = ("ffmpeg -y -i %s -qscale:v 2 -threads 1 -f image2 %s" % (os.path.join(opt.avi_dir,opt.reference,'video.avi'),os.path.join(opt.frames_dir,opt.reference,'%06d.jpg'))) +command = ("ffmpeg -y -i %s -qscale:v 2 -threads 1 -f image2 %s" % (os.path.join(opt.avi_dir,opt.reference,'video.avi'),os.path.join(opt.frames_dir,opt.reference,'%06d.jpg'))) output = subprocess.call(command, shell=True, stdout=None) -command = ("ffmpeg -y -i %s -ac 1 -vn -acodec pcm_s16le -ar 16000 %s" % (os.path.join(opt.avi_dir,opt.reference,'video.avi'),os.path.join(opt.avi_dir,opt.reference,'audio.wav'))) +command = ("ffmpeg -y -i %s -ac 1 -vn -acodec pcm_s16le -ar 16000 %s" % (os.path.join(opt.avi_dir,opt.reference,'video.avi'),os.path.join(opt.avi_dir,opt.reference,'audio.wav'))) output = subprocess.call(command, shell=True, stdout=None) # ========== FACE DETECTION ==========