Пример #1
0
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
Пример #3
0
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]
Пример #8
0
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)