Skip to content

Commit

Permalink
init commit
Browse files Browse the repository at this point in the history
  • Loading branch information
clcarwin committed Nov 21, 2017
1 parent de34931 commit f1a1364
Show file tree
Hide file tree
Showing 80 changed files with 1,127 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,5 @@ ENV/

# mypy
.mypy_cache/

*.pth
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,19 @@
# SFD_pytorch
A PyTorch Implementation of Single Shot Scale-invariant Face Detector.

# Eval
```
python wider_eval_pytorch.py
cd eval/eval_tools_old-version
octave wider_eval_pytorch.m
```

# Test
```
python test.py --model data/s3fd_convert.pth --path data/test01.jpg
```
![output](data/test01_output.png)

# References
[SFD](https://github.com/sfzhang15/SFD)
95 changes: 95 additions & 0 deletions bbox.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
from __future__ import print_function
import os,sys,cv2,random,datetime,time,math
import argparse
import numpy as np
import torch

try:
from iou import IOU
except:
# IOU cython speedup 10x
def IOU(ax1,ay1,ax2,ay2,bx1,by1,bx2,by2):
sa = abs((ax2-ax1)*(ay2-ay1))
sb = abs((bx2-bx1)*(by2-by1))
x1,y1 = max(ax1,bx1),max(ay1,by1)
x2,y2 = min(ax2,bx2),min(ay2,by2)
w = x2 - x1
h = y2 - y1
if w<0 or h<0: return 0.0
else: return 1.0*w*h/(sa+sb-w*h)

def bboxlog(x1,y1,x2,y2,axc,ayc,aww,ahh):
xc,yc,ww,hh = (x2+x1)/2,(y2+y1)/2,x2-x1,y2-y1
dx,dy = (xc-axc)/aww,(yc-ayc)/ahh
dw,dh = math.log(ww/aww),math.log(hh/ahh)
return dx,dy,dw,dh

def bboxloginv(dx,dy,dw,dh,axc,ayc,aww,ahh):
xc,yc = dx*aww+axc, dy*ahh+ayc
ww,hh = math.exp(dw)*aww,math.exp(dh)*ahh
x1,x2,y1,y2 = xc-ww/2,xc+ww/2,yc-hh/2,yc+hh/2
return x1,y1,x2,y2

def nms(dets, thresh):
if 0==len(dets): return []
x1,y1,x2,y2,scores = dets[:, 0],dets[:, 1],dets[:, 2],dets[:, 3],dets[:, 4]
areas = (x2 - x1 + 1) * (y2 - y1 + 1)
order = scores.argsort()[::-1]

keep = []
while order.size > 0:
i = order[0]
keep.append(i)
xx1,yy1 = np.maximum(x1[i], x1[order[1:]]),np.maximum(y1[i], y1[order[1:]])
xx2,yy2 = np.minimum(x2[i], x2[order[1:]]),np.minimum(y2[i], y2[order[1:]])

w,h = np.maximum(0.0, xx2 - xx1 + 1),np.maximum(0.0, yy2 - yy1 + 1)
ovr = w*h / (areas[i] + areas[order[1:]] - w*h)

inds = np.where(ovr <= thresh)[0]
order = order[inds + 1]

return keep

def encode(matched, priors, variances):
"""Encode the variances from the priorbox layers into the ground truth boxes
we have matched (based on jaccard overlap) with the prior boxes.
Args:
matched: (tensor) Coords of ground truth for each prior in point-form
Shape: [num_priors, 4].
priors: (tensor) Prior boxes in center-offset form
Shape: [num_priors,4].
variances: (list[float]) Variances of priorboxes
Return:
encoded boxes (tensor), Shape: [num_priors, 4]
"""

# dist b/t match center and prior's center
g_cxcy = (matched[:, :2] + matched[:, 2:])/2 - priors[:, :2]
# encode variance
g_cxcy /= (variances[0] * priors[:, 2:])
# match wh / prior wh
g_wh = (matched[:, 2:] - matched[:, :2]) / priors[:, 2:]
g_wh = torch.log(g_wh) / variances[1]
# return target for smooth_l1_loss
return torch.cat([g_cxcy, g_wh], 1) # [num_priors,4]

def decode(loc, priors, variances):
"""Decode locations from predictions using priors to undo
the encoding we did for offset regression at train time.
Args:
loc (tensor): location predictions for loc layers,
Shape: [num_priors,4]
priors (tensor): Prior boxes in center-offset form.
Shape: [num_priors,4].
variances: (list[float]) Variances of priorboxes
Return:
decoded bounding box predictions
"""

boxes = torch.cat((
priors[:, :2] + loc[:, :2] * variances[0] * priors[:, 2:],
priors[:, 2:] * torch.exp(loc[:, 2:] * variances[1])), 1)
boxes[:, :2] -= boxes[:, 2:] / 2
boxes[:, 2:] += boxes[:, :2]
return boxes
Binary file added data/test01.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added data/test01_output.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions eval/eval_tools_old-version/boxoverlap.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
function o = boxoverlap(a, b)
% Compute the symmetric intersection over union overlap between a set of
% bounding boxes in a and a single bounding box in b.
%
% a a matrix where each row specifies a bounding box
% b a single bounding box

% AUTORIGHTS
% -------------------------------------------------------
% Copyright (C) 2011-2012 Ross Girshick
% Copyright (C) 2008, 2009, 2010 Pedro Felzenszwalb, Ross Girshick
%
% This file is part of the voc-releaseX code
% (http://people.cs.uchicago.edu/~rbg/latent/)
% and is available under the terms of an MIT-like license
% provided in COPYING. Please retain this notice and
% COPYING if you use this file (or a portion of it) in
% your project.
% -------------------------------------------------------

x1 = max(a(:,1), b(1));
y1 = max(a(:,2), b(2));
x2 = min(a(:,3), b(3));
y2 = min(a(:,4), b(4));

w = x2-x1+1;
h = y2-y1+1;
inter = w.*h;
aarea = (a(:,3)-a(:,1)+1) .* (a(:,4)-a(:,2)+1);
barea = (b(3)-b(1)+1) * (b(4)-b(2)+1);
% intersection over union overlap
o = inter ./ (aarea+barea-inter);
% set invalid entries to 0 overlap
o(w <= 0) = 0;
o(h <= 0) = 0;
99 changes: 99 additions & 0 deletions eval/eval_tools_old-version/evaluation.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
function evaluation(norm_pred_list,gt_dir,setting_name,setting_class,legend_name)
load(gt_dir);
if ~exist(sprintf('./plot/baselines/Val/%s/%s',setting_class,legend_name),'dir')
mkdir(sprintf('./plot/baselines/Val/%s/%s',setting_class,legend_name));
end
IoU_thresh = 0.5;
event_num = 61;
thresh_num = 1000;
org_pr_cruve = zeros(thresh_num,2);
count_face = 0;

for i = 1:event_num
img_list = file_list{i};
gt_bbx_list = face_bbx_list{i};
pred_list = norm_pred_list{i};
sub_gt_list = gt_list{i};
img_pr_info_list = cell(length(img_list),1);

fprintf('%s, current event %d\n',setting_name,i);
for j = 1:length(img_list)
gt_bbx = gt_bbx_list{j};
pred_info = pred_list{j};
keep_index = sub_gt_list{j};
count_face = count_face + length(keep_index);

if isempty(gt_bbx) || isempty(pred_info)
continue;
end
ignore = zeros(size(gt_bbx,1),1);
if ~isempty(keep_index)
ignore(keep_index) = 1;
end

[pred_recall, proposal_list] = image_evaluation(pred_info, gt_bbx, ignore, IoU_thresh);

img_pr_info = image_pr_info(thresh_num, pred_info, proposal_list, pred_recall);
img_pr_info_list{j} = img_pr_info;
end
for j = 1:length(img_list)
img_pr_info = img_pr_info_list{j};
if ~isempty(img_pr_info)
org_pr_cruve(:,1) = org_pr_cruve(:,1) + img_pr_info(:,1);
org_pr_cruve(:,2) = org_pr_cruve(:,2) + img_pr_info(:,2);
end
end
end
pr_cruve = dataset_pr_info(thresh_num, org_pr_cruve, count_face);
% save(sprintf('./plot/baselines/Val/%s/%s/wider_pr_info_%s_%s.mat',setting_class,legend_name,legend_name,setting_name),'pr_cruve','legend_name','-v7.3');
save(sprintf('./plot/baselines/Val/%s/%s/wider_pr_info_%s_%s.mat',setting_class,legend_name,legend_name,setting_name),'pr_cruve','legend_name','-v7');
end

function [pred_recall,proposal_list] = image_evaluation(pred_info, gt_bbx, ignore, IoU_thresh)
pred_recall = zeros(size(pred_info,1),1);
recall_list = zeros(size(gt_bbx,1),1);
proposal_list = zeros(size(pred_info,1),1);
proposal_list = proposal_list + 1;
pred_info(:,3) = pred_info(:,1) + pred_info(:,3);
pred_info(:,4) = pred_info(:,2) + pred_info(:,4);
gt_bbx(:,3) = gt_bbx(:,1) + gt_bbx(:,3);
gt_bbx(:,4) = gt_bbx(:,2) + gt_bbx(:,4);
for h = 1:size(pred_info,1)
overlap_list = boxoverlap(gt_bbx, pred_info(h,1:4));
[max_overlap, idx] = max(overlap_list);
if max_overlap >= IoU_thresh
if (ignore(idx) == 0)
recall_list(idx) = -1;
proposal_list(h) = -1;
elseif (recall_list(idx)==0)
recall_list(idx) = 1;
end
end
r_keep_index = find(recall_list == 1);
pred_recall(h) = length(r_keep_index);
end
end

function img_pr_info = image_pr_info(thresh_num, pred_info, proposal_list, pred_recall)
img_pr_info = zeros(thresh_num,2);
for t = 1:thresh_num
thresh = 1-t/thresh_num;
r_index = find(pred_info(:,5)>=thresh,1,'last');
if (isempty(r_index))
img_pr_info(t,2) = 0;
img_pr_info(t,1) = 0;
else
p_index = find(proposal_list(1:r_index) == 1);
img_pr_info(t,1) = length(p_index);
img_pr_info(t,2) = pred_recall(r_index);
end
end
end

function pr_cruve = dataset_pr_info(thresh_num, org_pr_cruve, count_face)
pr_cruve = zeros(thresh_num,2);
for i = 1:thresh_num
pr_cruve(i,1) = org_pr_cruve(i,2)/org_pr_cruve(i,1);
pr_cruve(i,2) = org_pr_cruve(i,2)/count_face;
end
end
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
56 changes: 56 additions & 0 deletions eval/eval_tools_old-version/nms.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
function pick = nms(boxes, overlap)
% top = nms(boxes, overlap)
% Non-maximum suppression. (FAST VERSION)
% Greedily select high-scoring detections and skip detections
% that are significantly covered by a previously selected
% detection.
%
% NOTE: This is adapted from Pedro Felzenszwalb's version (nms.m),
% but an inner loop has been eliminated to significantly speed it
% up in the case of a large number of boxes

% Copyright (C) 2011-12 by Tomasz Malisiewicz
% All rights reserved.
%
% This file is part of the Exemplar-SVM library and is made
% available under the terms of the MIT license (see COPYING file).
% Project homepage: https://github.com/quantombone/exemplarsvm


if isempty(boxes)
pick = [];
return;
end

x1 = boxes(:,1);
y1 = boxes(:,2);
x2 = boxes(:,3);
y2 = boxes(:,4);
s = boxes(:,end);

area = (x2-x1+1) .* (y2-y1+1);
[vals, I] = sort(s);

pick = s*0;
counter = 1;
while ~isempty(I)
last = length(I);
i = I(last);
pick(counter) = i;
counter = counter + 1;

xx1 = max(x1(i), x1(I(1:last-1)));
yy1 = max(y1(i), y1(I(1:last-1)));
xx2 = min(x2(i), x2(I(1:last-1)));
yy2 = min(y2(i), y2(I(1:last-1)));

w = max(0.0, xx2-xx1+1);
h = max(0.0, yy2-yy1+1);

inter = w.*h;
o = inter ./ (area(i) + area(I(1:last-1)) - inter);

I = I(find(o<=overlap));
end

pick = pick(1:(counter-1));
31 changes: 31 additions & 0 deletions eval/eval_tools_old-version/norm_score.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
function norm_pred_list = norm_score(org_pred_list)

event_num = 61;
norm_pred_list = cell(event_num,1);
max_score = realmin('single');
min_score = realmax('single');
parfor i = 1:event_num
pred_list = org_pred_list{i};
for j = 1:size(pred_list,1)
if(isempty(pred_list{j}))
continue;
end
score_list = pred_list{j}(:,5);
max_score = max(max_score,max(score_list));
min_score = min(min_score,min(score_list));
end
end

parfor i = 1:event_num
fprintf('Norm prediction: current event %d\n',i);
pred_list = org_pred_list{i};
for j = 1:size(pred_list,1)
if(isempty(pred_list{j}))
continue;
end
score_list = pred_list{j}(:,5);
norm_score_list = (score_list - min_score)/(max_score - min_score);
pred_list{j}(:,5) = norm_score_list;
end
norm_pred_list{i} = pred_list;
end
9 changes: 9 additions & 0 deletions eval/eval_tools_old-version/plot/VOCap.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
function ap = VOCap(rec,prec)

mrec=[0 ; rec ; 1];
mpre=[0 ; prec ; 0];
for i=numel(mpre)-1:-1:1
mpre(i)=max(mpre(i),mpre(i+1));
end
i=find(mrec(2:end)~=mrec(1:end-1))+1;
ap=sum((mrec(i)-mrec(i-1)).*mpre(i));
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
37 changes: 37 additions & 0 deletions eval/eval_tools_old-version/plot/plot_pr.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
function plot_pr(propose,recall,lendge_name,seting_class,setting_name,dateset_class)
model_num = size(propose,1);
figure1 = figure('PaperSize',[20.98 29.68],'Color',[1 1 1]);
axes1 = axes('Parent',figure1,...
'LineWidth',2,...
'FontSize',15,...
'FontName','Times New Roman',...
'FontWeight','bold');
box(axes1,'on');
hold on;

LineColor = colormap(hsv(model_num));
for i=1:model_num
plot(propose{i},recall{i},...
'MarkerEdgeColor',LineColor(i,:),...
'MarkerFaceColor',LineColor(i,:),...
'LineWidth',4,...
'Color',LineColor(i,:))
hleg = legend(lendge_name{:},'Location','SouthEast');
grid on;
hold on;
end
xlim([0,1]);
ylim([0,1]);
xlabel('Recall');
ylabel('Precision');

% savename = sprintf('./plot/figure/%s/wider_pr_cruve_%s_%s.pdf',dateset_class,seting_class,setting_name);
savename = sprintf('./plot/figure_%s_wider_pr_cruve_%s_%s.jpg',dateset_class,seting_class,setting_name);
print("-djpg",savename)
% saveTightFigure(gcf,savename);
clear gcf;
hold off;




Loading

0 comments on commit f1a1364

Please sign in to comment.