sczhou commited on
Commit
4d7b6e8
·
1 Parent(s): 50489a6

add colorization and inpainting.

Browse files
README.md CHANGED
@@ -22,22 +22,17 @@ S-Lab, Nanyang Technological University
22
 
23
  **[<font color=#d1585d>News</font>]**: :whale: *We regret to inform you that the release of our code will be postponed from its earlier plan. Nevertheless, we assure you that it will be made available **by the end of this April**. Thank you for your understanding and patience. Our apologies for any inconvenience this may cause.*
24
  ### Update
 
25
  - **2023.02.10**: Include `dlib` as a new face detector option, it produces more accurate face identity.
26
- - **2022.10.05**: Support video input `--input_path [YOUR_VIDOE.mp4]`. Try it to enhance your videos! :clapper:
27
  - **2022.09.14**: Integrated to :hugs: [Hugging Face](https://huggingface.co/spaces). Try out online demo! [![Hugging Face](https://img.shields.io/badge/Demo-%F0%9F%A4%97%20Hugging%20Face-blue)](https://huggingface.co/spaces/sczhou/CodeFormer)
28
  - **2022.09.09**: Integrated to :rocket: [Replicate](https://replicate.com/explore). Try out online demo! [![Replicate](https://img.shields.io/badge/Demo-%F0%9F%9A%80%20Replicate-blue)](https://replicate.com/sczhou/codeformer)
29
- - **2022.09.04**: Add face upsampling `--face_upsample` for high-resolution AI-created face enhancement.
30
- - **2022.08.23**: Some modifications on face detection and fusion for better AI-created face enhancement.
31
- - **2022.08.07**: Integrate [Real-ESRGAN](https://github.com/xinntao/Real-ESRGAN) to support background image enhancement.
32
- - **2022.07.29**: Integrate new face detectors of `['RetinaFace'(default), 'YOLOv5']`.
33
- - **2022.07.17**: Add Colab demo of CodeFormer. <a href="https://colab.research.google.com/drive/1m52PNveE4PBhYrecj34cnpEeiHcC5LTb?usp=sharing"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="google colab logo"></a>
34
- - **2022.07.16**: Release inference code for face restoration. :blush:
35
- - **2022.06.21**: This repo is created.
36
 
37
  ### TODO
38
- - [ ] Add checkpoint for face inpainting
39
- - [ ] Add checkpoint for face colorization
40
  - [ ] Add training code and config files
 
 
41
  - [x] ~~Add background image enhancement~~
42
 
43
  #### :panda_face: Try Enhancing Old Photos / Fixing AI-arts
@@ -75,34 +70,41 @@ conda activate codeformer
75
  # install python dependencies
76
  pip3 install -r requirements.txt
77
  python basicsr/setup.py develop
78
- conda install -c conda-forge dlib (only for dlib face detector)
79
  ```
80
  <!-- conda install -c conda-forge dlib -->
81
 
82
  ### Quick Inference
83
 
84
  #### Download Pre-trained Models:
85
- Download the facelib and dlib pretrained models from [[Google Drive](https://drive.google.com/drive/folders/1b_3qwrzY_kTQh0-SnBoGBgOrJ_PLZSKm?usp=sharing) | [OneDrive](https://entuedu-my.sharepoint.com/:f:/g/personal/s200094_e_ntu_edu_sg/EvDxR7FcAbZMp_MA9ouq7aQB8XTppMb3-T0uGZ_2anI2mg?e=DXsJFo)] to the `weights/facelib` folder. You can manually download the pretrained models OR download by running the following command.
86
  ```
87
  python scripts/download_pretrained_models.py facelib
88
  python scripts/download_pretrained_models.py dlib (only for dlib face detector)
89
  ```
90
 
91
- Download the CodeFormer pretrained models from [[Google Drive](https://drive.google.com/drive/folders/1CNNByjHDFt0b95q54yMVp6Ifo5iuU6QS?usp=sharing) | [OneDrive](https://entuedu-my.sharepoint.com/:f:/g/personal/s200094_e_ntu_edu_sg/EoKFj4wo8cdIn2-TY2IV6CYBhZ0pIG4kUOeHdPR_A5nlbg?e=AO8UN9)] to the `weights/CodeFormer` folder. You can manually download the pretrained models OR download by running the following command.
92
  ```
93
  python scripts/download_pretrained_models.py CodeFormer
94
  ```
95
 
96
  #### Prepare Testing Data:
97
- You can put the testing images in the `inputs/TestWhole` folder. If you would like to test on cropped and aligned faces, you can put them in the `inputs/cropped_faces` folder.
 
 
 
 
98
 
99
 
100
- #### Testing on Face Restoration:
101
  [Note] If you want to compare CodeFormer in your paper, please run the following command indicating `--has_aligned` (for cropped and aligned face), as the command for the whole image will involve a process of face-background fusion that may damage hair texture on the boundary, which leads to unfair comparison.
102
 
 
 
 
103
  🧑🏻 Face Restoration (cropped and aligned face)
104
  ```
105
- # For cropped and aligned faces
106
  python inference_codeformer.py -w 0.5 --has_aligned --input_path [image folder]|[image path]
107
  ```
108
 
@@ -121,14 +123,25 @@ conda install -c conda-forge ffmpeg
121
  ```
122
  ```
123
  # For video clips
124
- # video path should end with '.mp4'|'.mov'|'.avi'
125
  python inference_codeformer.py --bg_upsampler realesrgan --face_upsample -w 1.0 --input_path [video path]
126
  ```
127
 
 
 
 
 
 
 
128
 
129
- Fidelity weight *w* lays in [0, 1]. Generally, smaller *w* tends to produce a higher-quality result, while larger *w* yields a higher-fidelity result.
 
 
 
 
 
 
130
 
131
- The results will be saved in the `results` folder.
132
 
133
  ### Citation
134
  If our work is useful for your research, please consider citing:
 
22
 
23
  **[<font color=#d1585d>News</font>]**: :whale: *We regret to inform you that the release of our code will be postponed from its earlier plan. Nevertheless, we assure you that it will be made available **by the end of this April**. Thank you for your understanding and patience. Our apologies for any inconvenience this may cause.*
24
  ### Update
25
+ - **2023.04.09**: Add features of inpainting and colorization for cropped and aligned face images.
26
  - **2023.02.10**: Include `dlib` as a new face detector option, it produces more accurate face identity.
27
+ - **2022.10.05**: Support video input `--input_path [YOUR_VIDEO.mp4]`. Try it to enhance your videos! :clapper:
28
  - **2022.09.14**: Integrated to :hugs: [Hugging Face](https://huggingface.co/spaces). Try out online demo! [![Hugging Face](https://img.shields.io/badge/Demo-%F0%9F%A4%97%20Hugging%20Face-blue)](https://huggingface.co/spaces/sczhou/CodeFormer)
29
  - **2022.09.09**: Integrated to :rocket: [Replicate](https://replicate.com/explore). Try out online demo! [![Replicate](https://img.shields.io/badge/Demo-%F0%9F%9A%80%20Replicate-blue)](https://replicate.com/sczhou/codeformer)
30
+ - [**More**](docs/history_changelog.md)
 
 
 
 
 
 
31
 
32
  ### TODO
 
 
33
  - [ ] Add training code and config files
34
+ - [x] Add checkpoint and script for face inpainting
35
+ - [x] Add checkpoint and script for face colorization
36
  - [x] ~~Add background image enhancement~~
37
 
38
  #### :panda_face: Try Enhancing Old Photos / Fixing AI-arts
 
70
  # install python dependencies
71
  pip3 install -r requirements.txt
72
  python basicsr/setup.py develop
73
+ conda install -c conda-forge dlib (only for face detection or cropping with dlib)
74
  ```
75
  <!-- conda install -c conda-forge dlib -->
76
 
77
  ### Quick Inference
78
 
79
  #### Download Pre-trained Models:
80
+ Download the facelib and dlib pretrained models from [[Releases](https://github.com/sczhou/CodeFormer/releases) | [Google Drive](https://drive.google.com/drive/folders/1b_3qwrzY_kTQh0-SnBoGBgOrJ_PLZSKm?usp=sharing) | [OneDrive](https://entuedu-my.sharepoint.com/:f:/g/personal/s200094_e_ntu_edu_sg/EvDxR7FcAbZMp_MA9ouq7aQB8XTppMb3-T0uGZ_2anI2mg?e=DXsJFo)] to the `weights/facelib` folder. You can manually download the pretrained models OR download by running the following command:
81
  ```
82
  python scripts/download_pretrained_models.py facelib
83
  python scripts/download_pretrained_models.py dlib (only for dlib face detector)
84
  ```
85
 
86
+ Download the CodeFormer pretrained models from [[Releases](https://github.com/sczhou/CodeFormer/releases) | [Google Drive](https://drive.google.com/drive/folders/1CNNByjHDFt0b95q54yMVp6Ifo5iuU6QS?usp=sharing) | [OneDrive](https://entuedu-my.sharepoint.com/:f:/g/personal/s200094_e_ntu_edu_sg/EoKFj4wo8cdIn2-TY2IV6CYBhZ0pIG4kUOeHdPR_A5nlbg?e=AO8UN9)] to the `weights/CodeFormer` folder. You can manually download the pretrained models OR download by running the following command:
87
  ```
88
  python scripts/download_pretrained_models.py CodeFormer
89
  ```
90
 
91
  #### Prepare Testing Data:
92
+ You can put the testing images in the `inputs/TestWhole` folder. If you would like to test on cropped and aligned faces, you can put them in the `inputs/cropped_faces` folder. You can get the cropped and aligned faces by running the following command:
93
+ ```
94
+ # you may need to install dlib via: conda install -c conda-forge dlib
95
+ python scripts/crop_align_face.py -i [input folder] -o [output folder]
96
+ ```
97
 
98
 
99
+ #### Testing:
100
  [Note] If you want to compare CodeFormer in your paper, please run the following command indicating `--has_aligned` (for cropped and aligned face), as the command for the whole image will involve a process of face-background fusion that may damage hair texture on the boundary, which leads to unfair comparison.
101
 
102
+ Fidelity weight *w* lays in [0, 1]. Generally, smaller *w* tends to produce a higher-quality result, while larger *w* yields a higher-fidelity result. The results will be saved in the `results` folder.
103
+
104
+
105
  🧑🏻 Face Restoration (cropped and aligned face)
106
  ```
107
+ # For cropped and aligned faces (512x512)
108
  python inference_codeformer.py -w 0.5 --has_aligned --input_path [image folder]|[image path]
109
  ```
110
 
 
123
  ```
124
  ```
125
  # For video clips
126
+ # Video path should end with '.mp4'|'.mov'|'.avi'
127
  python inference_codeformer.py --bg_upsampler realesrgan --face_upsample -w 1.0 --input_path [video path]
128
  ```
129
 
130
+ 🌈 Face Colorization (cropped and aligned face)
131
+ ```
132
+ # For cropped and aligned faces (512x512)
133
+ # Colorize black and white or faded photo
134
+ python inference_inpainting.py --input_path [image folder]|[image path]
135
+ ```
136
 
137
+ 🎨 Face Inpainting (cropped and aligned face)
138
+ ```
139
+ # For cropped and aligned faces (512x512)
140
+ # Inputs could be masked by white brush using a image editing app, e.g., Photoshop
141
+ # (check out the examples in inputs/masked_faces)
142
+ python inference_colorization.py --input_path [image folder]|[image path]
143
+ ```
144
 
 
145
 
146
  ### Citation
147
  If our work is useful for your research, please consider citing:
basicsr/utils/logger.py CHANGED
@@ -67,10 +67,10 @@ class MessageLogger():
67
  message += f'{k}: {v:.4e} '
68
  # tensorboard logger
69
  if self.use_tb_logger:
70
- if k.startswith('l_'):
71
- self.tb_logger.add_scalar(f'losses/{k}', v, current_iter)
72
- else:
73
- self.tb_logger.add_scalar(k, v, current_iter)
74
  self.logger.info(message)
75
 
76
 
 
67
  message += f'{k}: {v:.4e} '
68
  # tensorboard logger
69
  if self.use_tb_logger:
70
+ # if k.startswith('l_'):
71
+ # self.tb_logger.add_scalar(f'losses/{k}', v, current_iter)
72
+ # else:
73
+ self.tb_logger.add_scalar(k, v, current_iter)
74
  self.logger.info(message)
75
 
76
 
docs/history_changelog.md ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # History of Changelog
2
+
3
+ - **2023.04.09**: Add features of inpainting and colorization for cropped face images.
4
+ - **2023.02.10**: Include `dlib` as a new face detector option, it produces more accurate face identity.
5
+ - **2022.10.05**: Support video input `--input_path [YOUR_VIDEO.mp4]`. Try it to enhance your videos! :clapper:
6
+ - **2022.09.14**: Integrated to :hugs: [Hugging Face](https://huggingface.co/spaces). Try out online demo! [![Hugging Face](https://img.shields.io/badge/Demo-%F0%9F%A4%97%20Hugging%20Face-blue)](https://huggingface.co/spaces/sczhou/CodeFormer)
7
+ - **2022.09.09**: Integrated to :rocket: [Replicate](https://replicate.com/explore). Try out online demo! [![Replicate](https://img.shields.io/badge/Demo-%F0%9F%9A%80%20Replicate-blue)](https://replicate.com/sczhou/codeformer)
8
+ - **2022.09.04**: Add face upsampling `--face_upsample` for high-resolution AI-created face enhancement.
9
+ - **2022.08.23**: Some modifications on face detection and fusion for better AI-created face enhancement.
10
+ - **2022.08.07**: Integrate [Real-ESRGAN](https://github.com/xinntao/Real-ESRGAN) to support background image enhancement.
11
+ - **2022.07.29**: Integrate new face detectors of `['RetinaFace'(default), 'YOLOv5']`.
12
+ - **2022.07.17**: Add Colab demo of CodeFormer. <a href="https://colab.research.google.com/drive/1m52PNveE4PBhYrecj34cnpEeiHcC5LTb?usp=sharing"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="google colab logo"></a>
13
+ - **2022.07.16**: Release inference code for face restoration. :blush:
14
+ - **2022.06.21**: This repo is created.
inference_colorization.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import cv2
3
+ import argparse
4
+ import glob
5
+ import torch
6
+ from torchvision.transforms.functional import normalize
7
+ from basicsr.utils import imwrite, img2tensor, tensor2img
8
+ from basicsr.utils.download_util import load_file_from_url
9
+ from basicsr.utils.misc import get_device
10
+ from basicsr.utils.registry import ARCH_REGISTRY
11
+
12
+ pretrain_model_url = 'https://github.com/sczhou/CodeFormer/releases/download/v0.1.0/codeformer_colorization.pth'
13
+
14
+ if __name__ == '__main__':
15
+ # device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
16
+ device = get_device()
17
+ parser = argparse.ArgumentParser()
18
+
19
+ parser.add_argument('-i', '--input_path', type=str, default='./inputs/gray_faces',
20
+ help='Input image or folder. Default: inputs/gray_faces')
21
+ parser.add_argument('-o', '--output_path', type=str, default=None,
22
+ help='Output folder. Default: results/<input_name>')
23
+ parser.add_argument('--suffix', type=str, default=None,
24
+ help='Suffix of the restored faces. Default: None')
25
+ args = parser.parse_args()
26
+
27
+ # ------------------------ input & output ------------------------
28
+ print('[NOTE] The input face images should be aligned and cropped to a resolution of 512x512.')
29
+ if args.input_path.endswith(('jpg', 'jpeg', 'png', 'JPG', 'JPEG', 'PNG')): # input single img path
30
+ input_img_list = [args.input_path]
31
+ result_root = f'results/test_colorization_img'
32
+ else: # input img folder
33
+ if args.input_path.endswith('/'): # solve when path ends with /
34
+ args.input_path = args.input_path[:-1]
35
+ # scan all the jpg and png images
36
+ input_img_list = sorted(glob.glob(os.path.join(args.input_path, '*.[jpJP][pnPN]*[gG]')))
37
+ result_root = f'results/{os.path.basename(args.input_path)}'
38
+
39
+ if not args.output_path is None: # set output path
40
+ result_root = args.output_path
41
+
42
+ test_img_num = len(input_img_list)
43
+
44
+ # ------------------ set up CodeFormer restorer -------------------
45
+ net = ARCH_REGISTRY.get('CodeFormer')(dim_embd=512, codebook_size=1024, n_head=8, n_layers=9,
46
+ connect_list=['32', '64', '128']).to(device)
47
+
48
+ # ckpt_path = 'weights/CodeFormer/codeformer.pth'
49
+ ckpt_path = load_file_from_url(url=pretrain_model_url,
50
+ model_dir='weights/CodeFormer', progress=True, file_name=None)
51
+ checkpoint = torch.load(ckpt_path)['params_ema']
52
+ net.load_state_dict(checkpoint)
53
+ net.eval()
54
+
55
+ # -------------------- start to processing ---------------------
56
+ for i, img_path in enumerate(input_img_list):
57
+ img_name = os.path.basename(img_path)
58
+ basename, ext = os.path.splitext(img_name)
59
+ print(f'[{i+1}/{test_img_num}] Processing: {img_name}')
60
+ input_face = cv2.imread(img_path)
61
+ assert input_face.shape[:2] == (512, 512), 'Input resolution must be 512x512 for colorization.'
62
+ # input_face = cv2.resize(input_face, (512, 512), interpolation=cv2.INTER_LINEAR)
63
+ input_face = img2tensor(input_face / 255., bgr2rgb=True, float32=True)
64
+ normalize(input_face, (0.5, 0.5, 0.5), (0.5, 0.5, 0.5), inplace=True)
65
+ input_face = input_face.unsqueeze(0).to(device)
66
+ try:
67
+ with torch.no_grad():
68
+ # w is fixed to 0 since we didn't train the Stage III for colorization
69
+ output_face = net(input_face, w=0, adain=True)[0]
70
+ save_face = tensor2img(output_face, rgb2bgr=True, min_max=(-1, 1))
71
+ del output_face
72
+ torch.cuda.empty_cache()
73
+ except Exception as error:
74
+ print(f'\tFailed inference for CodeFormer: {error}')
75
+ save_face = tensor2img(input_face, rgb2bgr=True, min_max=(-1, 1))
76
+
77
+ save_face = save_face.astype('uint8')
78
+
79
+ # save face
80
+ if args.suffix is not None:
81
+ basename = f'{basename}_{args.suffix}'
82
+ save_restore_path = os.path.join(result_root, f'{basename}.png')
83
+ imwrite(save_face, save_restore_path)
84
+
85
+ print(f'\nAll results are saved in {result_root}')
86
+
inference_inpainting.py ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import cv2
3
+ import argparse
4
+ import glob
5
+ import torch
6
+ from torchvision.transforms.functional import normalize
7
+ from basicsr.utils import imwrite, img2tensor, tensor2img
8
+ from basicsr.utils.download_util import load_file_from_url
9
+ from basicsr.utils.misc import get_device
10
+ from basicsr.utils.registry import ARCH_REGISTRY
11
+
12
+ pretrain_model_url = 'https://github.com/sczhou/CodeFormer/releases/download/v0.1.0/codeformer_inpainting.pth'
13
+
14
+ if __name__ == '__main__':
15
+ # device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
16
+ device = get_device()
17
+ parser = argparse.ArgumentParser()
18
+
19
+ parser.add_argument('-i', '--input_path', type=str, default='./inputs/masked_faces',
20
+ help='Input image or folder. Default: inputs/masked_faces')
21
+ parser.add_argument('-o', '--output_path', type=str, default=None,
22
+ help='Output folder. Default: results/<input_name>')
23
+ parser.add_argument('--suffix', type=str, default=None,
24
+ help='Suffix of the restored faces. Default: None')
25
+ args = parser.parse_args()
26
+
27
+ # ------------------------ input & output ------------------------
28
+ print('[NOTE] The input face images should be aligned and cropped to a resolution of 512x512.')
29
+ if args.input_path.endswith(('jpg', 'jpeg', 'png', 'JPG', 'JPEG', 'PNG')): # input single img path
30
+ input_img_list = [args.input_path]
31
+ result_root = f'results/test_inpainting_img'
32
+ else: # input img folder
33
+ if args.input_path.endswith('/'): # solve when path ends with /
34
+ args.input_path = args.input_path[:-1]
35
+ # scan all the jpg and png images
36
+ input_img_list = sorted(glob.glob(os.path.join(args.input_path, '*.[jpJP][pnPN]*[gG]')))
37
+ result_root = f'results/{os.path.basename(args.input_path)}'
38
+
39
+ if not args.output_path is None: # set output path
40
+ result_root = args.output_path
41
+
42
+ test_img_num = len(input_img_list)
43
+
44
+ # ------------------ set up CodeFormer restorer -------------------
45
+ net = ARCH_REGISTRY.get('CodeFormer')(dim_embd=512, codebook_size=512, n_head=8, n_layers=9,
46
+ connect_list=['32', '64', '128']).to(device)
47
+
48
+ # ckpt_path = 'weights/CodeFormer/codeformer.pth'
49
+ ckpt_path = load_file_from_url(url=pretrain_model_url,
50
+ model_dir='weights/CodeFormer', progress=True, file_name=None)
51
+ checkpoint = torch.load(ckpt_path)['params_ema']
52
+ net.load_state_dict(checkpoint)
53
+ net.eval()
54
+
55
+ # -------------------- start to processing ---------------------
56
+ for i, img_path in enumerate(input_img_list):
57
+ img_name = os.path.basename(img_path)
58
+ basename, ext = os.path.splitext(img_name)
59
+ print(f'[{i+1}/{test_img_num}] Processing: {img_name}')
60
+ input_face = cv2.imread(img_path)
61
+ assert input_face.shape[:2] == (512, 512), 'Input resolution must be 512x512 for inpainting.'
62
+ # input_face = cv2.resize(input_face, (512, 512), interpolation=cv2.INTER_LINEAR)
63
+ input_face = img2tensor(input_face / 255., bgr2rgb=True, float32=True)
64
+ normalize(input_face, (0.5, 0.5, 0.5), (0.5, 0.5, 0.5), inplace=True)
65
+ input_face = input_face.unsqueeze(0).to(device)
66
+ try:
67
+ with torch.no_grad():
68
+ mask = torch.zeros(512, 512)
69
+ m_ind = torch.sum(input_face[0], dim=0)
70
+ mask[m_ind==3] = 1.0
71
+ mask = mask.view(1, 1, 512, 512).to(device)
72
+ # w is fixed to 1, adain=False for inpainting
73
+ output_face = net(input_face, w=1, adain=False)[0]
74
+ output_face = (1-mask)*input_face + mask*output_face
75
+ save_face = tensor2img(output_face, rgb2bgr=True, min_max=(-1, 1))
76
+ del output_face
77
+ torch.cuda.empty_cache()
78
+ except Exception as error:
79
+ print(f'\tFailed inference for CodeFormer: {error}')
80
+ save_face = tensor2img(input_face, rgb2bgr=True, min_max=(-1, 1))
81
+
82
+ save_face = save_face.astype('uint8')
83
+
84
+ # save face
85
+ if args.suffix is not None:
86
+ basename = f'{basename}_{args.suffix}'
87
+ save_restore_path = os.path.join(result_root, f'{basename}.png')
88
+ imwrite(save_face, save_restore_path)
89
+
90
+ print(f'\nAll results are saved in {result_root}')
91
+
inputs/gray_faces/067_David_Beckham_00.png ADDED
inputs/gray_faces/089_Miley_Cyrus_00.png ADDED
inputs/gray_faces/099_Victoria_Beckham_00.png ADDED
inputs/gray_faces/111_Alexa_Chung_00.png ADDED
inputs/gray_faces/132_Robert_Downey_Jr_00.png ADDED
inputs/gray_faces/158_Jimmy_Fallon_00.png ADDED
inputs/gray_faces/161_Zac_Efron_00.png ADDED
inputs/gray_faces/169_John_Lennon_00.png ADDED
inputs/gray_faces/170_Marilyn_Monroe_00.png ADDED
inputs/gray_faces/Einstein01.png ADDED
inputs/gray_faces/Einstein02.png ADDED
inputs/gray_faces/Hepburn01.png ADDED
inputs/gray_faces/Hepburn02.png ADDED
inputs/masked_faces/00105.png ADDED
inputs/masked_faces/00108.png ADDED
inputs/masked_faces/00169.png ADDED
inputs/masked_faces/00588.png ADDED
inputs/masked_faces/00664.png ADDED
scripts/crop_align_face.py CHANGED
@@ -13,19 +13,25 @@ requirements:
13
  # http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
14
  """
15
 
16
- import cv2
17
- import dlib
18
  import glob
19
  import numpy as np
20
- import os
21
  import PIL
22
  import PIL.Image
23
  import scipy
24
  import scipy.ndimage
25
- import sys
26
  import argparse
 
 
 
 
 
 
27
 
28
  # download model from: http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
 
 
 
29
  predictor = dlib.shape_predictor('weights/dlib/shape_predictor_68_face_landmarks-fbdc2cb8.dat')
30
 
31
 
@@ -39,9 +45,9 @@ def get_landmark(filepath, only_keep_largest=True):
39
  dets = detector(img, 1)
40
 
41
  # Shangchen modified
42
- print("Number of faces detected: {}".format(len(dets)))
43
  if only_keep_largest:
44
- print('Detect several faces and only keep the largest.')
45
  face_areas = []
46
  for k, d in enumerate(dets):
47
  face_area = (d.right() - d.left()) * (d.bottom() - d.top())
@@ -50,16 +56,16 @@ def get_landmark(filepath, only_keep_largest=True):
50
  largest_idx = face_areas.index(max(face_areas))
51
  d = dets[largest_idx]
52
  shape = predictor(img, d)
53
- print("Part 0: {}, Part 1: {} ...".format(
54
- shape.part(0), shape.part(1)))
55
  else:
56
  for k, d in enumerate(dets):
57
- print("Detection {}: Left: {} Top: {} Right: {} Bottom: {}".format(
58
- k, d.left(), d.top(), d.right(), d.bottom()))
59
  # Get the landmarks/parts for the face in box d.
60
  shape = predictor(img, d)
61
- print("Part 0: {}, Part 1: {} ...".format(
62
- shape.part(0), shape.part(1)))
63
 
64
  t = list(shape.parts())
65
  a = []
@@ -171,7 +177,7 @@ def align_face(filepath, out_path):
171
  img = img.resize((output_size, output_size), PIL.Image.ANTIALIAS)
172
 
173
  # Save aligned image.
174
- print('saveing: ', out_path)
175
  img.save(out_path)
176
 
177
  return img, np.max(quad[:, 0]) - np.min(quad[:, 0])
@@ -179,14 +185,21 @@ def align_face(filepath, out_path):
179
 
180
  if __name__ == '__main__':
181
  parser = argparse.ArgumentParser()
182
- parser.add_argument('--in_dir', type=str, default='./inputs/whole_imgs')
183
- parser.add_argument('--out_dir', type=str, default='./inputs/cropped_faces')
184
  args = parser.parse_args()
185
 
186
- img_list = sorted(glob.glob(f'{args.in_dir}/*.png'))
187
- img_list = sorted(img_list)
 
 
 
 
 
188
 
189
- for in_path in img_list:
 
 
190
  out_path = os.path.join(args.out_dir, in_path.split("/")[-1])
191
  out_path = out_path.replace('.jpg', '.png')
192
  size_ = align_face(in_path, out_path)
 
13
  # http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
14
  """
15
 
16
+ import os
 
17
  import glob
18
  import numpy as np
 
19
  import PIL
20
  import PIL.Image
21
  import scipy
22
  import scipy.ndimage
 
23
  import argparse
24
+ from basicsr.utils.download_util import load_file_from_url
25
+
26
+ try:
27
+ import dlib
28
+ except ImportError:
29
+ print('Please install dlib by running:' 'conda install -c conda-forge dlib')
30
 
31
  # download model from: http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
32
+ shape_predictor_url = 'https://github.com/sczhou/CodeFormer/releases/download/v0.1.0/shape_predictor_68_face_landmarks-fbdc2cb8.dat'
33
+ ckpt_path = load_file_from_url(url=shape_predictor_url,
34
+ model_dir='weights/dlib', progress=True, file_name=None)
35
  predictor = dlib.shape_predictor('weights/dlib/shape_predictor_68_face_landmarks-fbdc2cb8.dat')
36
 
37
 
 
45
  dets = detector(img, 1)
46
 
47
  # Shangchen modified
48
+ print("\tNumber of faces detected: {}".format(len(dets)))
49
  if only_keep_largest:
50
+ print('\tOnly keep the largest.')
51
  face_areas = []
52
  for k, d in enumerate(dets):
53
  face_area = (d.right() - d.left()) * (d.bottom() - d.top())
 
56
  largest_idx = face_areas.index(max(face_areas))
57
  d = dets[largest_idx]
58
  shape = predictor(img, d)
59
+ # print("Part 0: {}, Part 1: {} ...".format(
60
+ # shape.part(0), shape.part(1)))
61
  else:
62
  for k, d in enumerate(dets):
63
+ # print("Detection {}: Left: {} Top: {} Right: {} Bottom: {}".format(
64
+ # k, d.left(), d.top(), d.right(), d.bottom()))
65
  # Get the landmarks/parts for the face in box d.
66
  shape = predictor(img, d)
67
+ # print("Part 0: {}, Part 1: {} ...".format(
68
+ # shape.part(0), shape.part(1)))
69
 
70
  t = list(shape.parts())
71
  a = []
 
177
  img = img.resize((output_size, output_size), PIL.Image.ANTIALIAS)
178
 
179
  # Save aligned image.
180
+ # print('saveing: ', out_path)
181
  img.save(out_path)
182
 
183
  return img, np.max(quad[:, 0]) - np.min(quad[:, 0])
 
185
 
186
  if __name__ == '__main__':
187
  parser = argparse.ArgumentParser()
188
+ parser.add_argument('-i', '--in_dir', type=str, default='./inputs/whole_imgs')
189
+ parser.add_argument('-o', '--out_dir', type=str, default='./inputs/cropped_faces')
190
  args = parser.parse_args()
191
 
192
+ if args.out_dir.endswith('/'): # solve when path ends with /
193
+ args.out_dir = args.out_dir[:-1]
194
+ dir_name = os.path.abspath(args.out_dir)
195
+ os.makedirs(dir_name, exist_ok=True)
196
+
197
+ img_list = sorted(glob.glob(os.path.join(args.in_dir, '*.[jpJP][pnPN]*[gG]')))
198
+ test_img_num = len(img_list)
199
 
200
+ for i, in_path in enumerate(img_list):
201
+ img_name = os.path.basename(in_path)
202
+ print(f'[{i+1}/{test_img_num}] Processing: {img_name}')
203
  out_path = os.path.join(args.out_dir, in_path.split("/")[-1])
204
  out_path = out_path.replace('.jpg', '.png')
205
  size_ = align_face(in_path, out_path)