Exemple #1
0
def main():
    args = parse_args()

    model = init_model(args.config,
                       args.checkpoint,
                       device=torch.device('cuda', args.device))

    result = inpainting_inference(model, args.masked_img_path, args.mask_path)
    result = tensor2img(result, min_max=(-1, 1))[..., ::-1]

    mmcv.imwrite(result, args.save_path)
    if args.imshow:
        mmcv.imshow(result, 'predicted inpainting result')
Exemple #2
0
def main():
    args = parse_args()

    model = init_model(args.config,
                       args.checkpoint,
                       device=torch.device('cuda', args.device))

    output = restoration_inference(model, args.img_path)
    output = tensor2img(output)
    # print(np.shape(output))
    mmcv.imwrite(output, args.save_path)
    if args.imshow:
        mmcv.imshow(output, 'predicted restoration result')
def main():
    args = parse_args()

    model = init_model(
        args.config, args.checkpoint, device=torch.device('cuda', args.device))

    output = restoration_video_inference(model, args.input_dir,
                                         args.window_size, args.filename_tmpl)
    for i in range(0, output.size(1)):
        output_i = output[:, i, :, :, :]
        output_i = tensor2img(output_i)
        save_path_i = f'{args.output_dir}/{i:08d}.png'

        mmcv.imwrite(output_i, save_path_i)
Exemple #4
0
    def forward_test(self,
                     lq,
                     gt=None,
                     meta=None,
                     save_image=False,
                     save_path=None,
                     iteration=None):
        """Testing forward function.

        Args:
            lq (Tensor): LQ Tensor with shape (n, c, h, w).
            gt (Tensor): GT Tensor with shape (n, c, h, w). Default: None.
            save_image (bool): Whether to save image. Default: False.
            save_path (str): Path to save image. Default: None.
            iteration (int): Iteration for the saving image name.
                Default: None.

        Returns:
            dict: Output results.
        """
        output = self.generator(lq)

        # normalize from [-1, 1] to [0, 1]
        output = (output + 1) / 2.0

        if self.test_cfg is not None and self.test_cfg.get('metrics', None):
            assert gt is not None, (
                'evaluation with metrics must have gt images.')
            gt = (gt + 1) / 2.0  # normalize from [-1, 1] to [0, 1]
            results = dict(eval_result=self.evaluate(output, gt))
        else:
            results = dict(lq=lq.cpu(), output=output.cpu())
            if gt is not None:
                results['gt'] = gt.cpu()

        # save image
        if save_image:
            lq_path = meta[0]['lq_path']
            folder_name = osp.splitext(osp.basename(lq_path))[0]
            if isinstance(iteration, numbers.Number):
                save_path = osp.join(save_path, folder_name,
                                     f'{folder_name}-{iteration + 1:06d}.png')
            elif iteration is None:
                save_path = osp.join(save_path, f'{folder_name}.png')
            else:
                raise ValueError('iteration should be number or None, '
                                 f'but got {type(iteration)}')
            mmcv.imwrite(tensor2img(output), save_path)

        return results
    def _save_image(meta, iteration, save_path, output):
        """Save the image.

        Args:
            meta (list[dict]): Meta data, such as path of target file.
                Default: None. These dictionaries should contain
                'target_path' (str of a path) or 'inputs_path' (list of str)
            iteration (int): Iteration for the saving image name.
                Default: None.
            save_path (str): Path to save image. Default: None.
            output (Tensor): Output image.
        """

        if output.ndim == 4:  # an image
            img_name = meta[0]['key'].replace('/', '_')
            if isinstance(iteration, numbers.Number):
                save_path = osp.join(save_path,
                                     f'{img_name}-{iteration + 1:06d}.png')
            elif iteration is None:
                save_path = osp.join(save_path, f'{img_name}.png')
            else:
                raise ValueError('iteration should be number or None, '
                                 f'but got {type(iteration)}')
            mmcv.imwrite(tensor2img(output), save_path)
        elif output.ndim == 5:  # a sequence
            folder_name = meta[0]['key'].split('/')[0]
            for i in range(0, output.size(1)):
                if isinstance(iteration, numbers.Number):
                    save_path_i = osp.join(save_path, folder_name,
                                           f'{i:08d}-{iteration + 1:06d}.png')
                elif iteration is None:
                    save_path_i = osp.join(save_path, folder_name,
                                           f'{i:08d}.png')
                else:
                    raise ValueError('iteration should be number or None, '
                                     f'but got {type(iteration)}')
                mmcv.imwrite(tensor2img(output[:, i, :, :, :]), save_path_i)
Exemple #6
0
    def evaluate(self, output, gt):
        """Evaluation function.

        If the output contains multiple frames, we compute the metric
        one by one and take an average.

        Args:
            output (Tensor): Model output with shape (n, t, c, h, w).
            gt (Tensor): GT Tensor with shape (n, t, c, h, w).

        Returns:
            dict: Evaluation results.
        """
        crop_border = self.test_cfg.crop_border
        convert_to = self.test_cfg.get('convert_to', None)

        eval_result = dict()
        for metric in self.test_cfg.metrics:
            if output.ndim == 5:  # a sequence: (n, t, c, h, w)
                avg = []
                for i in range(0, output.size(1)):
                    output_i = tensor2img(output[:, i, :, :, :])
                    gt_i = tensor2img(gt[:, i, :, :, :])
                    avg.append(self.allowed_metrics[metric](
                        output_i, gt_i, crop_border, convert_to=convert_to))
                eval_result[metric] = np.mean(avg)
            elif output.ndim == 4:  # an image: (n, c, t, w), for Vimeo-90K-T
                output_img = tensor2img(output)
                gt_img = tensor2img(gt)
                value = self.allowed_metrics[metric](output_img,
                                                     gt_img,
                                                     crop_border,
                                                     convert_to=convert_to)
                eval_result[metric] = value

        return eval_result
def main():
    """ Demo for video restoration models.

    Note that we accept video as input/output, when 'input_dir'/'output_dir'
    is set to the path to the video. But using videos introduces video
    compression, which lowers the visual quality. If you want actual quality,
    please save them as separate images (.png).
    """

    args = parse_args()

    model = init_model(args.config,
                       args.checkpoint,
                       device=torch.device('cuda', args.device))

    output = restoration_video_inference(model, args.input_dir,
                                         args.window_size, args.start_idx,
                                         args.filename_tmpl, args.max_seq_len)

    file_extension = os.path.splitext(args.output_dir)[1]
    if file_extension in VIDEO_EXTENSIONS:  # save as video
        h, w = output.shape[-2:]
        fourcc = cv2.VideoWriter_fourcc(*'mp4v')
        video_writer = cv2.VideoWriter(args.output_dir, fourcc, 25, (w, h))
        for i in range(0, output.size(1)):
            img = tensor2img(output[:, i, :, :, :])
            video_writer.write(img.astype(np.uint8))
        cv2.destroyAllWindows()
        video_writer.release()
    else:
        for i in range(args.start_idx, args.start_idx + output.size(1)):
            output_i = output[:, i - args.start_idx, :, :, :]
            output_i = tensor2img(output_i)
            save_path_i = f'{args.output_dir}/{args.filename_tmpl.format(i)}'

            mmcv.imwrite(output_i, save_path_i)
    def merge_frames(input_tensors, output_tensors):
        """merge input frames and output frames.

        This is a basic function, interpolate a frame between the given two
        frames.

        Args:
            input_tensors (Tensor): The input frames with shape [n, 2, c, h, w]
            output_tensors (Tensor): The output frames with shape
                [n, 1, c, h, w].

        Returns:
            list[np.array]: The final frames.
                in_frame, out_frame, in_frame, out_frame, in_frame ...
        """

        num_frames = input_tensors.shape[0]
        result = []
        for i in range(num_frames):
            result.append(tensor2img(input_tensors[i, 0]))
            result.append(tensor2img(output_tensors[i, 0]))
        result.append(tensor2img(input_tensors[-1, 1]))

        return result
Exemple #9
0
def main():
    args = parse_args()

    if not os.path.isfile(args.img_path):
        raise ValueError('It seems that you did not input a valid '
                         '"image_path". Please double check your input, or '
                         'you may want to use "restoration_video_demo.py" '
                         'for video restoration.')

    model = init_model(args.config,
                       args.checkpoint,
                       device=torch.device('cuda', args.device))

    output = restoration_inference(model, args.img_path)
    output = tensor2img(output)

    mmcv.imwrite(output, args.save_path)
    if args.imshow:
        mmcv.imshow(output, 'predicted restoration result')
            else:
                torch.cuda.empty_cache()
                # Inpainting
                t0 = time.time()
                ## create mask for inpainting
                mask = b_boxes_manager.mask(image)
                ## Save temp mask file temporarly
                mask_path = "temp.png"
                Image.fromarray(mask).save("temp.png")
                ## init the inpainter
                model = init_model(config["Inpainter"]["configuration"],
                                   config["Inpainter"]["pretrained_model"],
                                   device=device)
                ## inpaint
                result = inpainting_inference(model, image_path, mask_path)[0]
                result = tensor2img(result, min_max=(-1, 1))
                os.remove("temp.png")
                print("Inpainting time : {:.3f}".format(time.time() - t0))

                # Translation
                t0 = time.time()
                result = b_boxes_manager.fill_translation(
                    result,
                    same_block_th=config["same_block_th"],
                    translation_service=config["translation_service"],
                    src_language=src_language,
                    dest_language=dst_language,
                    result_path=result_path)
                print("Translation time : {:.3f}".format(time.time() - t0))

                # open results
Exemple #11
0
    def forward_test(self,
                     lq,
                     gt=None,
                     meta=None,
                     save_image=False,
                     save_path=None,
                     iteration=None,
                     multi_scale=False):
        """Testing forward function.

        Args:
            lq (Tensor): LQ Tensor with shape (n, c, h, w). (n, t, c, h, w).
            gt (Tensor): GT Tensor with shape (n, c, h, w). Default: None.
            save_image (bool): Whether to save image. Default: False.
            save_path (str): Path to save image. Default: None.
            iteration (int): Iteration for the saving image name.
                Default: None.

        Returns:
            dict: Output results.
        """
        # todo add multi_scale test code
        if multi_scale:
            output = self.multi_scale_test(lq)
        else:
            output = self.generator(lq)
            # output = self.generator(torch.flip(lq, (-1, )))  # w
            # output = self.generator(torch.flip(lq, (-2, )))  # h
            # output = self.generator(torch.flip(lq, (-2, -1)))  # wh
        if self.test_cfg is not None and self.test_cfg.get('metrics', None):
            assert gt is not None, (
                'evaluation with metrics must have gt images.')
            results = dict(eval_result=self.evaluate(output, gt))
        else:
            results = dict(lq=lq.cpu(), output=output.cpu())
            if gt is not None:
                results['gt'] = gt.cpu()

        # save image
        if save_image:
            gt_path = meta[0]['gt_path'][0]
            folder_name = meta[0]['key'].split('/')[0]
            frame_name = osp.splitext(osp.basename(gt_path))[0]
            center_frame_idx = int(frame_name)
            # if center_frame_idx % 10 == 0:
            if True:
                if isinstance(iteration, numbers.Number):
                    save_path = osp.join(
                        save_path, folder_name,
                        f'{frame_name}-{iteration + 1:06d}.png')
                elif iteration is None:
                    save_path = osp.join(save_path, folder_name,
                                         f'{frame_name}.png')

                else:
                    raise ValueError('iteration should be number or None, '
                                     f'but got {type(iteration)}')
                output = tensor2img(output)

                # print(np.shape(output))
                # output_crop = output[:536, :, :]
                output_crop = output[:-8, :, :]

                # print(np.shape(output_crop))
                mmcv.imwrite(output_crop, save_path)

        return results
Exemple #12
0
    def forward_test(self,
                     img_a,
                     img_b,
                     meta,
                     save_image=False,
                     save_path=None,
                     iteration=None):
        """Forward function for testing.

        Args:
            img_a (Tensor): Input image from domain A.
            img_b (Tensor): Input image from domain B.
            meta (list[dict]): Input meta data.
            save_image (bool, optional): If True, results will be saved as
                images. Default: False.
            save_path (str, optional): If given a valid str path, the results
                will be saved in this path. Default: None.
            iteration (int, optional): Iteration number. Default: None.

        Returns:
            dict: Dict of forward and evaluation results for testing.
        """
        # No need for metrics during training for pix2pix. And
        # this is a special trick in pix2pix original paper & implementation,
        # collecting the statistics of the test batch at test time.
        self.train()

        # necessary setup
        real_a, real_b, image_path = self.setup(img_a, img_b, meta)

        fake_b = self.generator(real_a)
        results = dict(real_a=real_a.cpu(),
                       fake_b=fake_b.cpu(),
                       real_b=real_b.cpu())

        # save image
        if save_image:
            assert save_path is not None
            folder_name = osp.splitext(osp.basename(image_path[0]))[0]
            if self.show_input:
                if iteration:
                    save_path = osp.join(
                        save_path, folder_name,
                        f'{folder_name}-{iteration + 1:06d}-ra-fb-rb.png')
                else:
                    save_path = osp.join(save_path,
                                         f'{folder_name}-ra-fb-rb.png')
                output = np.concatenate([
                    tensor2img(results['real_a'], min_max=(-1, 1)),
                    tensor2img(results['fake_b'], min_max=(-1, 1)),
                    tensor2img(results['real_b'], min_max=(-1, 1))
                ],
                                        axis=1)
            else:
                if iteration:
                    save_path = osp.join(
                        save_path, folder_name,
                        f'{folder_name}-{iteration + 1:06d}-fb.png')
                else:
                    save_path = osp.join(save_path, f'{folder_name}-fb.png')
                output = tensor2img(results['fake_b'], min_max=(-1, 1))
            flag = mmcv.imwrite(output, save_path)
            results['saved_flag'] = flag

        return results
Exemple #13
0
def test_tensor2img():
    tensor_4d_1 = torch.FloatTensor(2, 3, 4, 4).uniform_(0, 1)
    tensor_4d_2 = torch.FloatTensor(1, 3, 4, 4).uniform_(0, 1)
    tensor_4d_3 = torch.FloatTensor(3, 1, 4, 4).uniform_(0, 1)
    tensor_4d_4 = torch.FloatTensor(1, 1, 4, 4).uniform_(0, 1)
    tensor_3d_1 = torch.FloatTensor(3, 4, 4).uniform_(0, 1)
    tensor_3d_2 = torch.FloatTensor(3, 6, 6).uniform_(0, 1)
    tensor_3d_3 = torch.FloatTensor(1, 6, 6).uniform_(0, 1)
    tensor_2d = torch.FloatTensor(4, 4).uniform_(0, 1)

    with pytest.raises(TypeError):
        # input is not a tensor
        tensor2img(4)
    with pytest.raises(TypeError):
        # input is not a list of tensors
        tensor2img([tensor_3d_1, 4])
    with pytest.raises(ValueError):
        # unsupported 5D tensor
        tensor2img(torch.FloatTensor(2, 2, 3, 4, 4).uniform_(0, 1))

    # 4d
    rlt = tensor2img(tensor_4d_1, out_type=np.uint8, min_max=(0, 1))
    assert rlt.dtype == np.uint8
    tensor_4d_1_np = make_grid(tensor_4d_1, nrow=1, normalize=False).numpy()
    tensor_4d_1_np = np.transpose(tensor_4d_1_np[[2, 1, 0], :, :], (1, 2, 0))
    np.testing.assert_almost_equal(rlt, (tensor_4d_1_np * 255).round())

    rlt = tensor2img(tensor_4d_2, out_type=np.uint8, min_max=(0, 1))
    assert rlt.dtype == np.uint8
    tensor_4d_2_np = tensor_4d_2.squeeze().numpy()
    tensor_4d_2_np = np.transpose(tensor_4d_2_np[[2, 1, 0], :, :], (1, 2, 0))
    np.testing.assert_almost_equal(rlt, (tensor_4d_2_np * 255).round())

    rlt = tensor2img(tensor_4d_3, out_type=np.uint8, min_max=(0, 1))
    assert rlt.dtype == np.uint8
    tensor_4d_3_np = make_grid(tensor_4d_3, nrow=1, normalize=False).numpy()
    tensor_4d_3_np = np.transpose(tensor_4d_3_np[[2, 1, 0], :, :], (1, 2, 0))
    np.testing.assert_almost_equal(rlt, (tensor_4d_3_np * 255).round())

    rlt = tensor2img(tensor_4d_4, out_type=np.uint8, min_max=(0, 1))
    assert rlt.dtype == np.uint8
    tensor_4d_4_np = tensor_4d_4.squeeze().numpy()
    np.testing.assert_almost_equal(rlt, (tensor_4d_4_np * 255).round())

    # 3d
    rlt = tensor2img([tensor_3d_1, tensor_3d_2],
                     out_type=np.uint8,
                     min_max=(0, 1))
    assert rlt[0].dtype == np.uint8
    tensor_3d_1_np = tensor_3d_1.numpy()
    tensor_3d_1_np = np.transpose(tensor_3d_1_np[[2, 1, 0], :, :], (1, 2, 0))
    tensor_3d_2_np = tensor_3d_2.numpy()
    tensor_3d_2_np = np.transpose(tensor_3d_2_np[[2, 1, 0], :, :], (1, 2, 0))
    np.testing.assert_almost_equal(rlt[0], (tensor_3d_1_np * 255).round())
    np.testing.assert_almost_equal(rlt[1], (tensor_3d_2_np * 255).round())

    rlt = tensor2img(tensor_3d_3, out_type=np.uint8, min_max=(0, 1))
    assert rlt.dtype == np.uint8
    tensor_3d_3_np = tensor_3d_3.squeeze().numpy()
    np.testing.assert_almost_equal(rlt, (tensor_3d_3_np * 255).round())

    # 2d
    rlt = tensor2img(tensor_2d, out_type=np.uint8, min_max=(0, 1))
    assert rlt.dtype == np.uint8
    tensor_2d_np = tensor_2d.numpy()
    np.testing.assert_almost_equal(rlt, (tensor_2d_np * 255).round())
    rlt = tensor2img(tensor_2d, out_type=np.float32, min_max=(0, 1))
    assert rlt.dtype == np.float32
    np.testing.assert_almost_equal(rlt, tensor_2d_np)

    rlt = tensor2img(tensor_2d, out_type=np.float32, min_max=(0.1, 0.5))
    assert rlt.dtype == np.float32
    tensor_2d_np = (np.clip(tensor_2d_np, 0.1, 0.5) - 0.1) / 0.4
    np.testing.assert_almost_equal(rlt, tensor_2d_np)
Exemple #14
0
    def forward_test(self,
                     masked_img,
                     mask,
                     save_image=False,
                     save_path=None,
                     iteration=None,
                     **kwargs):
        """Forward function for testing.

        Args:
            masked_img (torch.Tensor): Tensor with shape of (n, 3, h, w).
            mask (torch.Tensor): Tensor with shape of (n, 1, h, w).
            save_image (bool, optional): If True, results will be saved as
                image. Defaults to False.
            save_path (str, optional): If given a valid str, the reuslts will
                be saved in this path. Defaults to None.
            iteration (int, optional): Iteration number. Defaults to None.

        Returns:
            dict: Contain output results and eval metrics (if have).
        """
        mask_input = mask.expand_as(masked_img)
        mask_input = 1. - mask_input

        fake_res, final_mask = self.generator(masked_img, mask_input)
        fake_img = fake_res * mask + masked_img * (1. - mask)

        output = dict()
        eval_results = {}
        if self.eval_with_metrics:
            gt_img = kwargs['gt_img']
            data_dict = dict(gt_img=gt_img, fake_res=fake_res, mask=mask)
            for metric_name in self.test_cfg['metrics']:
                if metric_name in ['ssim', 'psnr']:
                    eval_results[metric_name] = self._eval_metrics[
                        metric_name](tensor2img(fake_img, min_max=(-1, 1)),
                                     tensor2img(gt_img, min_max=(-1, 1)))
                else:
                    eval_results[metric_name] = self._eval_metrics[
                        metric_name]()(data_dict).item()
            output['eval_results'] = eval_results
        else:
            output['fake_res'] = fake_res
            output['fake_img'] = fake_img
            output['final_mask'] = final_mask

        output['meta'] = None if 'meta' not in kwargs else kwargs['meta'][0]
        if save_image:
            assert save_image and save_path is not None, (
                'Save path should been given')
            assert output['meta'] is not None, (
                'Meta information should be given to save image.')

            tmp_filename = output['meta']['gt_img_path']
            filestem = Path(tmp_filename).stem
            if iteration is not None:
                filename = f'{filestem}_{iteration}.png'
            else:
                filename = f'{filestem}.png'
            mmcv.mkdir_or_exist(save_path)
            if kwargs.get('gt_img', None) is not None:
                img_list = [kwargs['gt_img']]
            else:
                img_list = []
            img_list.extend(
                [masked_img,
                 mask.expand_as(masked_img), fake_res, fake_img])
            img = torch.cat(img_list, dim=3).cpu()
            self.save_visualization(img, osp.join(save_path, filename))
            output['save_img_path'] = osp.abspath(
                osp.join(save_path, filename))
        return output
Exemple #15
0
    def forward_test(self,
                     lq,
                     gt=None,
                     meta=None,
                     save_image=False,
                     save_path=None,
                     iteration=None):
        """Testing forward function.

        Args:
            lq (Tensor): LQ image.
            gt (Tensor): GT image.
            meta (list[dict]): Meta data, such as path of GT file.
                Default: None.
            save_image (bool): Whether to save image. Default: False.
            save_path (str): Path to save image. Default: None.
            iteration (int): Iteration for the saving image name.
                Default: None.

        Returns:
            dict: Output results, which contain either key(s)
                1. 'eval_result'.
                2. 'lq', 'pred'.
                3. 'lq', 'pred', 'gt'.
        """

        # generator
        with torch.no_grad():
            sr_list, _ = self.generator.forward(lq)
            pred = sr_list[-1]
            pred = self.img_denormalize(pred)

            if gt is not None:
                gt = self.img_denormalize(gt)

        if self.test_cfg is not None and self.test_cfg.get('metrics', None):
            assert gt is not None, (
                'evaluation with metrics must have gt images.')
            results = dict(eval_result=self.evaluate(pred, gt))
        else:
            results = dict(lq=lq.cpu(), output=pred.cpu())
            if gt is not None:
                results['gt'] = gt.cpu()

        # save image
        if save_image:
            if 'gt_path' in meta[0]:
                pred_path = meta[0]['gt_path']
            else:
                pred_path = meta[0]['lq_path']
            folder_name = osp.splitext(osp.basename(pred_path))[0]
            if isinstance(iteration, numbers.Number):
                save_path = osp.join(save_path, folder_name,
                                     f'{folder_name}-{iteration + 1:06d}.png')
            elif iteration is None:
                save_path = osp.join(save_path, f'{folder_name}.png')
            else:
                raise ValueError('iteration should be number or None, '
                                 f'but got {type(iteration)}')
            mmcv.imwrite(tensor2img(pred), save_path)

        return results
Exemple #16
0
    def run_inpainting(self,
                       img_or_path,
                       mask_or_path,
                       dilate_kernel_size=19,
                       dilate_iter_num=3):
        """

        Args:
            img_or_path (str or np.ndarray): (h, w, 3) is in the range of [0, 255] with BGR channel;
            mask_or_path (str or np.ndarray): (h, w) is in the range of [0, 255], np.uint8;
            dilate_kernel_size (int): the kernel size of dilation;
            dilate_iter_num (int): the iterations of dilation;

        Returns:
            inpainting_result (np.ndarray): (h, w, 3), is in the range of [0, 255] with BGR channel.
        """

        # TODO, do not write the middle outputs to disk, and make them in memory.
        #  scaled_src_path, scaled_mask_path, scaled_inpainting_result_path

        img_name = str(time.time())
        img_path = os.path.join(self.temp_dir, img_name)

        if isinstance(img_or_path, str):
            src_img = cv2.imread(img_or_path)
        else:
            src_img = img_or_path.copy()
        """
        scaled image 
        """
        scaled_src_path = f"{img_path}_scaled.png"
        scaled_mask_path = f"{img_path}_mask.png"
        scaled_inpainting_result_path = f"{img_path}_inpainting.png"

        origin_h, origin_w = src_img.shape[:2]
        scaled_size = compute_scaled_size(
            (origin_w, origin_h), control_size=self.inpainting_control_size)

        scaled_src_img = cv2.resize(src_img, scaled_size)
        cv2.imwrite(scaled_src_path, scaled_src_img)
        """
        dilate mask
        """
        if isinstance(mask_or_path, str):
            mask = cv2.imread(mask_or_path, cv2.IMREAD_GRAYSCALE)
        else:
            # mask = (mask * 255).astype(np.uint8)
            mask = mask_or_path

        scaled_mask = cv2.resize(mask,
                                 scaled_size,
                                 interpolation=cv2.INTER_NEAREST)

        kernel = cv2.getStructuringElement(
            cv2.MORPH_ELLIPSE, (dilate_kernel_size, dilate_kernel_size))
        dilated_scaled_mask = cv2.dilate(scaled_mask,
                                         kernel,
                                         iterations=dilate_iter_num)
        cv2.imwrite(scaled_mask_path, dilated_scaled_mask)
        """
        inpainting result
        """
        scaled_result = inpainting_inference(self.inpainting_model,
                                             scaled_src_path, scaled_mask_path)
        # (h, w, 3) 0-255 bgr
        scaled_result = tensor2img(scaled_result, min_max=(-1, 1))[..., ::-1]
        cv2.imwrite(scaled_inpainting_result_path, scaled_result)
        """
        super-resolution
        """
        if self.cfg["use_sr"]:
            result = restoration_inference(self.sr_model,
                                           scaled_inpainting_result_path)
            result = tensor2img(result)
            result = cv2.resize(result, (origin_w, origin_h))
            result = result.astype(np.uint8)

        else:
            result = cv2.resize(scaled_result, (origin_w, origin_h))
            result = result.astype(np.uint8)

        os.remove(scaled_src_path)
        os.remove(scaled_mask_path)
        os.remove(scaled_inpainting_result_path)

        return result, dilated_scaled_mask
Exemple #17
0
    def forward_test(self,
                     lq,
                     gt=None,
                     meta=None,
                     save_image=False,
                     save_path=None,
                     iteration=None):
        """Testing forward function.

        Args:
            lq (Tensor): LQ Tensor with shape (n, t, c, h, w).
            gt (Tensor): GT Tensor with shape (n, t, c, h, w). Default: None.
            save_image (bool): Whether to save image. Default: False.
            save_path (str): Path to save image. Default: None.
            iteration (int): Iteration for the saving image name.
                Default: None.

        Returns:
            dict: Output results.
        """
        with torch.no_grad():
            output = self.generator(lq)

        # If the GT is an image (i.e. the center frame), the output sequence is
        # turned to an image.
        if gt is not None and gt.ndim == 4:
            t = output.size(1)
            if self.check_if_mirror_extended(lq):  # with mirror extension
                output = 0.5 * (output[:, t // 4] + output[:, -1 - t // 4])
            else:  # without mirror extension
                output = output[:, t // 2]

        if self.test_cfg is not None and self.test_cfg.get('metrics', None):
            assert gt is not None, (
                'evaluation with metrics must have gt images.')
            results = dict(eval_result=self.evaluate(output, gt))
        else:
            results = dict(lq=lq.cpu(), output=output.cpu())
            if gt is not None:
                results['gt'] = gt.cpu()

        # save image
        if save_image:
            if output.ndim == 4:  # an image, key = 000001/0000 (Vimeo-90K)
                img_name = meta[0]['key'].replace('/', '_')
                if isinstance(iteration, numbers.Number):
                    save_path = osp.join(
                        save_path, f'{img_name}-{iteration + 1:06d}.png')
                elif iteration is None:
                    save_path = osp.join(save_path, f'{img_name}.png')
                else:
                    raise ValueError('iteration should be number or None, '
                                     f'but got {type(iteration)}')
                mmcv.imwrite(tensor2img(output), save_path)
            elif output.ndim == 5:  # a sequence, key = 000
                folder_name = meta[0]['key'].split('/')[0]
                for i in range(0, output.size(1)):
                    if isinstance(iteration, numbers.Number):
                        save_path_i = osp.join(
                            save_path, folder_name,
                            f'{i:08d}-{iteration + 1:06d}.png')
                    elif iteration is None:
                        save_path_i = osp.join(save_path, folder_name,
                                               f'{i:08d}.png')
                    else:
                        raise ValueError('iteration should be number or None, '
                                         f'but got {type(iteration)}')
                    mmcv.imwrite(tensor2img(output[:, i, :, :, :]),
                                 save_path_i)

        return results
Exemple #18
0
    def forward_test(self,
                     lq,
                     lq_up,
                     ref,
                     ref_downup,
                     gt=None,
                     meta=None,
                     save_image=False,
                     save_path=None,
                     iteration=None):
        """Testing forward function.

        Args:
            lq (Tensor): LQ image
            gt (Tensor): GT image
            lq_up (Tensor): Upsampled LQ image
            ref (Tensor): Reference image
            ref_downup (Tensor): Image generated by sequentially applying
                bicubic down-sampling and up-sampling on reference image
            meta (list[dict]): Meta data, such as path of GT file.
                Default: None.
            save_image (bool): Whether to save image. Default: False.
            save_path (str): Path to save image. Default: None.
            iteration (int): Iteration for the saving image name.
                Default: None.

        Returns:
            dict: Output results, which contain either key(s)
                1. 'eval_result'.
                2. 'lq', 'pred'.
                3. 'lq', 'pred', 'gt'.
        """

        # generator
        with torch.no_grad():
            pred = self.forward_dummy(lq=lq,
                                      lq_up=lq_up,
                                      ref=ref,
                                      ref_downup=ref_downup)

        pred = (pred + 1.) / 2.
        if gt is not None:
            gt = (gt + 1.) / 2.

        if self.test_cfg is not None and self.test_cfg.get('metrics', None):
            assert gt is not None, (
                'evaluation with metrics must have gt images.')
            results = dict(eval_result=self.evaluate(pred, gt))
        else:
            results = dict(lq=lq.cpu(), output=pred.cpu())
            if gt is not None:
                results['gt'] = gt.cpu()

        # save image
        if save_image:
            if 'gt_path' in meta[0]:
                the_path = meta[0]['gt_path']
            else:
                the_path = meta[0]['lq_path']
            folder_name = osp.splitext(osp.basename(the_path))[0]
            if isinstance(iteration, numbers.Number):
                save_path = osp.join(save_path, folder_name,
                                     f'{folder_name}-{iteration + 1:06d}.png')
            elif iteration is None:
                save_path = osp.join(save_path, f'{folder_name}.png')
            else:
                raise ValueError('iteration should be number or None, '
                                 f'but got {type(iteration)}')
            mmcv.imwrite(tensor2img(pred), save_path)

        return results
Exemple #19
0
    def forward_test(self,
                     lq,
                     gt,
                     coord,
                     cell,
                     meta=None,
                     save_image=False,
                     save_path=None,
                     iteration=None):
        """Testing forward function.

        Args:
            lq (Tensor): LQ image.
            gt (Tensor): GT image.
            coord (Tensor): Coord tensor.
            cell (Tensor): Cell tensor.
            meta (list[dict]): Meta data, such as path of GT file.
                Default: None.
            save_image (bool): Whether to save image. Default: False.
            save_path (str): Path to save image. Default: None.
            iteration (int): Iteration for the saving image name.
                Default: None.

        Returns:
            dict: Output results, which contain either key(s)
                1. 'eval_result'.
                2. 'lq', 'pred'.
                3. 'lq', 'pred', 'gt'.
        """

        # norm
        self.lq_mean = self.lq_mean.to(lq)
        self.lq_std = self.lq_std.to(lq)
        lq = (lq - self.lq_mean) / self.lq_std

        # generator
        with torch.no_grad():
            pred = self.generator(lq, coord, cell, test_mode=True)
            self.gt_mean = self.gt_mean.to(pred)
            self.gt_std = self.gt_std.to(pred)
            pred = pred * self.gt_std + self.gt_mean
            pred.clamp_(0, 1)

        # reshape for eval
        ih, iw = lq.shape[-2:]
        s = math.sqrt(coord.shape[1] / (ih * iw))
        shape = [lq.shape[0], round(ih * s), round(iw * s), 3]
        pred = pred.view(*shape).permute(0, 3, 1, 2).contiguous()
        if gt is not None:
            gt = gt.view(*shape).permute(0, 3, 1, 2).contiguous()

        if self.test_cfg is not None and self.test_cfg.get('metrics', None):
            assert gt is not None, (
                'evaluation with metrics must have gt images.')
            results = dict(eval_result=self.evaluate(pred, gt))
        else:
            results = dict(lq=lq.cpu(), output=pred.cpu())
            if gt is not None:
                results['gt'] = gt.cpu()

        # save image
        if save_image:
            gt_path = meta[0]['gt_path']
            folder_name = osp.splitext(osp.basename(gt_path))[0]
            if isinstance(iteration, numbers.Number):
                save_path = osp.join(save_path, folder_name,
                                     f'{folder_name}-{iteration + 1:06d}.png')
            elif iteration is None:
                save_path = osp.join(save_path, f'{folder_name}.png')
            else:
                raise ValueError('iteration should be number or None, '
                                 f'but got {type(iteration)}')
            mmcv.imwrite(tensor2img(pred), save_path)

        return results