def pix2pix_results_to_video(path, destination=".", name_out="out"): """ Converts pix2pix results to a video :param name_out: name of output video :param destination: folder to save video :param path: str path of folder containing the result images """ files = list(map(str, get_files(path, '.png'))) files.sort(key=get_id) img_array = img_list_from_files(files) frames = pix2pix_results_to_frames(img_array) write_video(frames, destination, name_out)
def plot_test_results(data_path: str, save_path: str, max_figures_per_folder: int, from_subfolders: bool, wide3: bool, n: int): data_path = Path(data_path) save_path = Path(save_path) num = 0 if from_subfolders: folders = get_subfolders(data_path) else: folders = [data_path] file_arr = [] for folder in folders: files = get_files(folder, file_type='.png') file_arr.append(files) file_arr = [item for sublist in file_arr for item in sublist] cnt = 0 out = [] for file in tqdm(files[::100]): plot_files = [x for x in file_arr if x.name == file.name] if len(plot_files) == len(folders): for i, plot_file in enumerate(plot_files): row = cv2.imread(str(plot_file), 1) if cnt == 0: out.append(row) else: out[i] = np.concatenate((out[i], row)) if cnt >= n or file == files[::100][-1]: print(f"Saved figure {i}") cv2.imwrite( f"{save_path}/figure_{data_path.stem}_{plot_file.parent.stem}_{num}.png", out[i]) if i == len(plot_files) - 1: out = [] cnt = 0 num += 1 cnt += 1 if num >= max_figures_per_folder: print( f"Done. Saved {max_figures_per_folder} figure(s) for each folder at {save_path}" ) break
def get_matching_face_and_segmentation(path: Path, name: str, segmentation_path: str, random: bool = False): """ Returns the segmentation mask and the corresponding image to euther a random or a matching image :param path: Path to Parent Directory of the file location :param name: name of the file you want to find a match :param segmentation_path: path where the segmentation masks are saved :param random: if True returns a random sample :return: """ # test set range from 000* to 010* max_tries = 2 i = 0 valid = False while not valid: if random: files = get_files(path, ".png") file = random.choice(files) scale = 1 else: # use metrics to find best head file file, scale = get_matching_head_file(name) if file is None: return None, None, None file = path / file mask = get_segmentation_mask_from_name(file.name, segmentation_path) i += 1 if i >= max_tries: valid = True else: valid = _is_mask_valid(mask) file = path / file.name face = cv2.imread(str(file), 1) # enable if you read from pix2pix datasets assert face is not None, f"{path / file.name} not found." if face.shape[0] != face.shape[1]: face = face[:, :256, :] return face, mask, scale
def enhance_masks(data_path: str, processed_path: str): """ Enhances masks as outputted from pix2pix, EXPERIMENTAL :param processed_path: :param data_path: data path for masks :return: """ file_list = get_files(data_path, ".png") for file in file_list: src = cv.imread(cv.samples.findFile(str(file))) dilated_img = dilate(src, 2) output = clean_colors(dilated_img) im_rgb = cv.cvtColor(output, cv.COLOR_BGR2RGB) Image.fromarray(im_rgb).save(processed_path + file.stem + '.jpg', format='JPEG', subsampling=0, quality=100)
def calc_metric_for_folder(self, folder: Path): """ Calculates metrics for a folder :param folder: folder to calculate metrics :return: metrics of this folder """ if not self.loaded: self.load_model() # load metrics if existing existing_metrics = _load_metrics(folder) new_metrics = False files = get_files(folder, file_type=self.file_type) # code to rename keys if needed # loaded_metrics = existing_metrics.copy() # for key, item in loaded_metrics.items(): # if "_fake_B" in key: # key_new = key.replace('_fake_B', '') # existing_metrics[key_new] = existing_metrics.pop(key) # new_metrics = True for idx, file in enumerate(tqdm(files)): # check if file was already computed if existing_metrics is not None and file.name in existing_metrics: continue # compute metrics metric = self.get_metric_for_file(file) # update dict existing_metrics.update(metric) new_metrics = True if idx % 1000 is 0 and new_metrics: _save_metrics(existing_metrics, folder) # save metrics if new_metrics: _save_metrics(existing_metrics, folder) return existing_metrics
def get_faces(data_path, file_type=".jpg", overlay_keypoints=False, overlay_mask=True, align=False, margin_multiplier=0.45, reduce_by = 0): """ Detect faces, KEYPOINTS ARE ALIGNED ON ORIGINAL IMAGE!! :param overlay_mask: :param overlay_keypoints: :param align: align faces :param margin_multiplier: How much of additional image should be added to detected face region :param data_path: folder path to folder containing images :param file_type: image file type e.g. '.jpg' :return: dict containing cut out face, coordinates and the original image file name {'face_img': cropped_img, 'rect': (x, y, w, h), 'original_img': '1.jpg'} """ file_list = get_files(data_path, file_type) if file_list is None: print("No Files found. Exiting.") exit() if reduce_by > 0: # reduce to get only every 20th image print(f"Reducing file list by {reduce_by}!") file_list = file_list[::reduce_by] print('\nDetecting Faces:') extracted_faces = {} for f in tqdm(file_list): extracted_face = get_face(f, overlay_keypoints=overlay_keypoints, overlay_mask=overlay_mask, align=align, margin_multiplier=margin_multiplier) extracted_faces.update(extracted_face) return extracted_faces
embedding_list = resnet(img_stack) # .detach().cpu() embedding_dist = embedding_list[0] - embedding_list[1] dist = embedding_dist.norm().item() if percentage: return dist, ((2 - dist) * 50) elif embedding: return dist, embedding_list else: return dist if __name__ == '__main__': files = get_files( "/home/mo/experiments/masterthesis/face_generation/preprocess/images/test/", ".jpeg") aligned = [] names = [] for f in files: image = Image.open(f) img_cropped = mtcnn(image) if img_cropped is not None: aligned.append(img_cropped) names.append("Mo") aligned = torch.stack(aligned) embeddings = resnet(aligned) dists = [[(e1 - e2).norm().item() for e2 in embeddings]
def create_blending_dataset(data_path: str, file_type: str, frame_distance: int, out_resolution: int, with_segmentation: bool, use_fake_face: bool, fake_face_folder: str, border_perc: float, margin: float, save_path: str, do_not_transform: bool, do_fill_with_mean_color: bool, segmentation_path: str, mask_segmentation_path: str, search_subfolders: bool = False ): """ Create a blending dataset, where we remove the bounding box of the head and insert the old head again (but transformed) to learn the merging and blending. For test set generation you can also swap the head. """ if use_fake_face: print("No transformations.") do_not_transform = True else: print("Replacing with same data.") mask_segmentation_path = segmentation_path fake_face_folder = data_path if use_fake_face: print("-- Loading Metrics--\n") global metrics_fake, metrics_real, m m = MetricVisualizer() assert fake_face_folder != "", "No folder given for fake faces" metrics_fake = m.calc_metric_for_folder(folder=Path(fake_face_folder)) metrics_real = m.calc_metric_for_folder(folder=Path(data_path)) err_cnt = 0 # load all files print("-- Loading Files--\n") if search_subfolders: print("searching for subfolders") folders = get_subfolders(data_path, verbose=True) else: folders = [Path(data_path)] print("-- Processing Files--\n") for folder in tqdm(folders): files = get_files(Path(data_path) / folder, file_type) files.sort() # get corresponding pairs err_cont_ = _files_to_dataset(files, save_path, mask_segmentation_path, border_perc=border_perc, margin=margin, out_resolution=out_resolution, with_segmentation=with_segmentation, real_face=not use_fake_face, do_fill_with_mean_color=do_fill_with_mean_color, do_transform=not do_not_transform, segmentation_path=segmentation_path, fake_face_folder=fake_face_folder, frame_distance=frame_distance) err_cnt += err_cont_ print(f"Total errors: {err_cnt}")
def cutout_face(img_path: str, mask_path: str, processed_path: str, face_mask_path: str): """Cuts out face of person :param face_mask_path: :param processed_path: :param img_path: path of folder containing images :param mask_path: path of folder containing masks """ # get all filenames in the folders img_file_list = get_files(img_path, '.jpg') mask_file_list = get_files(mask_path, '.png') if img_file_list is None or mask_file_list is None: print("No image files found. Exiting") return if not len(img_file_list) == len(mask_file_list): print("Not the same amount og image files and mask files. Exiting") return # create folder for processed data processed_path = Path(processed_path) img_path = Path(img_path) face_mask_path = Path(face_mask_path) mask_path = Path(mask_path) processed_path.mkdir(exist_ok=True) for file in tqdm(img_file_list): # Load images face_img = Image.open(img_path / file.name) face_mask_img = Image.open(face_mask_path / f"{file.stem}.png") mask_img = Image.open(mask_path / f"{file.stem}.png") # Create dilated face mask as transparent, background is black face_mask_img_dilated = cv.imread( cv.samples.findFile(str(face_mask_path / f"{file.stem}.png"))) face_mask_img_dilated = dilate(face_mask_img_dilated, 20) face_mask_img_dilated = cv.cvtColor(face_mask_img_dilated, cv.COLOR_BGR2RGB) face_mask_img_dilated = Image.fromarray(face_mask_img_dilated) face_mask_img_dilated = make_color_transparent(face_mask_img_dilated, (255, 255, 255)) # Make face mask transparent, background is black face_mask_img = make_color_transparent(face_mask_img, (255, 255, 255)) # copy face mask onto the mask image overlaid_mask = overlay_two_images(mask_img, face_mask_img) # Make background transparent overlaid_mask = make_color_transparent(overlaid_mask, (0, 0, 0)) # overlay dilated face onto image overlaid_img = overlay_two_images(face_img, face_mask_img_dilated) # overlay mask onto image overlaid_mask = overlay_two_images(overlaid_img, overlaid_mask) # save result merge_images_side_by_side(overlaid_mask, overlaid_img).save( processed_path / file.name, format='PNG', subsampling=0, quality=100)