| 14 | from options.test_options import TestOptions |
| 15 | |
| 16 | class MorphFacesInTheWild: |
| 17 | def __init__(self, opt): |
| 18 | self._opt = opt |
| 19 | self._model = ModelsFactory.get_by_name(self._opt.model, self._opt) |
| 20 | self._model.set_eval() |
| 21 | self._transform = transforms.Compose([transforms.ToTensor(), |
| 22 | transforms.Normalize(mean=[0.5, 0.5, 0.5], |
| 23 | std=[0.5, 0.5, 0.5]) |
| 24 | ]) |
| 25 | |
| 26 | def morph_file(self, img_path, expresion): |
| 27 | img = cv_utils.read_cv2_img(img_path) |
| 28 | morphed_img = self._img_morph(img, expresion) |
| 29 | output_name = '%s_out.png' % os.path.basename(img_path) |
| 30 | self._save_img(morphed_img, output_name) |
| 31 | |
| 32 | def _img_morph(self, img, expresion): |
| 33 | bbs = face_recognition.face_locations(img) |
| 34 | if len(bbs) > 0: |
| 35 | y, right, bottom, x = bbs[0] |
| 36 | bb = x, y, (right - x), (bottom - y) |
| 37 | face = face_utils.crop_face_with_bb(img, bb) |
| 38 | face = face_utils.resize_face(face) |
| 39 | else: |
| 40 | face = face_utils.resize_face(img) |
| 41 | |
| 42 | morphed_face = self._morph_face(face, expresion) |
| 43 | |
| 44 | return morphed_face |
| 45 | |
| 46 | def _morph_face(self, face, expresion): |
| 47 | face = torch.unsqueeze(self._transform(Image.fromarray(face)), 0) |
| 48 | expresion = torch.unsqueeze(torch.from_numpy(expresion/5.0), 0) |
| 49 | test_batch = {'real_img': face, 'real_cond': expresion, 'desired_cond': expresion, 'sample_id': torch.FloatTensor(), 'real_img_path': []} |
| 50 | self._model.set_input(test_batch) |
| 51 | imgs, _ = self._model.forward(keep_data_for_visuals=False, return_estimates=True) |
| 52 | return imgs['concat'] |
| 53 | |
| 54 | def _save_img(self, img, filename): |
| 55 | filepath = os.path.join(self._opt.output_dir, filename) |
| 56 | img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) |
| 57 | cv2.imwrite(filepath, img) |
| 58 | |
| 59 | |
| 60 | def main(): |