summaryrefslogtreecommitdiff
path: root/megapixels/app/processors/face_extractor.py
diff options
context:
space:
mode:
authoradamhrv <adam@ahprojects.com>2019-01-16 13:30:16 +0100
committeradamhrv <adam@ahprojects.com>2019-01-16 13:30:16 +0100
commit65cb506ca182272e2701136097fd00c55dc6bd69 (patch)
treecc5be8e61a8d5173745be1d331b210e967e146b5 /megapixels/app/processors/face_extractor.py
parentfceeb3b7adbc8d522e9fe1c40e12e9a529199068 (diff)
change bbox to norm, refine face extractor
Diffstat (limited to 'megapixels/app/processors/face_extractor.py')
-rw-r--r--megapixels/app/processors/face_extractor.py42
1 files changed, 37 insertions, 5 deletions
diff --git a/megapixels/app/processors/face_extractor.py b/megapixels/app/processors/face_extractor.py
index 2666e090..f618cd36 100644
--- a/megapixels/app/processors/face_extractor.py
+++ b/megapixels/app/processors/face_extractor.py
@@ -44,6 +44,9 @@ class Extractor:
vec_flat[f'd{idx}'] = val
return vec_flat
+ def to_str(self, vec):
+ return ','.join([str(x) for x in vec])
+
def unflatten_df(self, df):
# convert from
return [df[f'd{i}'] for i in range(1,257)]
@@ -64,25 +67,54 @@ class ExtractorVGG(Extractor):
self.dnn = cv.dnn.readNetFromCaffe(fp_prototxt, fp_model)
self.feat_layer = self.dnn.getLayerNames()[-2]
- def extract(self, im, bbox_norm, padding=0.3):
+ def extract_jitter(self, im, bbox_norm):
+ '''(experimental) Extracts feature vector for face crop
+ :param im:
+ :param bbox_norm: (BBox) normalized
+ :param padding: (float) percent to extend ROI
+ :param jitters: not used here
+ :returns (list) of (float)'''
+ dim = im.shape[:2][::-1]
+ num_jitters = cfg.DEFAULT_NUM_JITTERS
+ padding = cfg.DEFAULT_FACE_PADDING_VGG_FACE2
+ pad_adj = .00875 * padding # percentage of padding to vary
+ paddings = np.linspace(padding - pad_adj, padding + pad_adj, num=num_jitters)
+ jitter_amt = cfg.DEFAULT_JITTER_AMT
+ vecs = []
+ for i in range(num_jitters):
+ bbox_norm_jit = bbox_norm.jitter(jitter_amt) # jitters w, h, center
+ bbox_ext = bbox_norm_jit.expand(paddings[i])
+ #bbox_ext = bbox_norm.expand(paddings[i])
+ x1,y1,x2,y2 = bbox_ext.to_dim(dim).to_xyxy()
+ im_crop = im[y1:y2, x1:x2]
+ # According to VGG, model trained using Bilinear interpolation (INTER_LINEAR)
+ im_crop = cv.resize(im_crop, self.dnn_dim, interpolation=cv.INTER_LINEAR)
+ blob = cv.dnn.blobFromImage(im_crop, 1.0, self.dnn_dim, self.dnn_mean)
+ self.dnn.setInput(blob)
+ vec = np.array(self.dnn.forward(self.feat_layer)[0])
+ vec_norm = vec/np.linalg.norm(vec) # normalize
+ vecs.append(vec_norm)
+ vec_norm = np.mean(np.array(vecs), axis=0)
+ return vec_norm
+
+ def extract(self, im, bbox_norm):
'''Extracts feature vector for face crop
:param im:
:param bbox_norm: (BBox) normalized
:param padding: (float) percent to extend ROI
:param jitters: not used here
:returns (list) of (float)'''
-
+ padding = cfg.DEFAULT_FACE_PADDING_VGG_FACE2
bbox_ext = bbox_norm.expand(padding)
dim = im.shape[:2][::-1]
- bbox_ext_dim = bbox_ext.to_dim(dim)
- x1,y1,x2,y2 = bbox_ext_dim.to_xyxy()
+ x1,y1,x2,y2 = bbox_ext.to_dim(dim).to_xyxy()
im = im[y1:y2, x1:x2]
# According to VGG, model trained using Bilinear interpolation (INTER_LINEAR)
im = cv.resize(im, self.dnn_dim, interpolation=cv.INTER_LINEAR)
blob = cv.dnn.blobFromImage(im, 1.0, self.dnn_dim, self.dnn_mean)
self.dnn.setInput(blob)
vec = np.array(self.dnn.forward(self.feat_layer)[0])
- vec_norm = np.array(vec)/np.linalg.norm(vec) # normalize
+ vec_norm = vec/np.linalg.norm(vec) # normalize
return vec_norm