diff options
| author | adamhrv <adam@ahprojects.com> | 2019-01-16 13:30:16 +0100 |
|---|---|---|
| committer | adamhrv <adam@ahprojects.com> | 2019-01-16 13:30:16 +0100 |
| commit | 65cb506ca182272e2701136097fd00c55dc6bd69 (patch) | |
| tree | cc5be8e61a8d5173745be1d331b210e967e146b5 /megapixels/app/processors/face_extractor.py | |
| parent | fceeb3b7adbc8d522e9fe1c40e12e9a529199068 (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.py | 42 |
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 |
