sczhou commited on
Commit
00fc5a8
·
1 Parent(s): 5b3ad16

support video input.

Browse files
Files changed (2) hide show
  1. README.md +16 -3
  2. inference_codeformer.py +41 -9
README.md CHANGED
@@ -23,6 +23,7 @@ S-Lab, Nanyang Technological University
23
 
24
  **[<font color=#d1585d>News</font>]**: :whale: *Due to copyright issues, we have to delay the release of the training code (expected by the end of this year). Please star and stay tuned for our future updates!*
25
  ### Update
 
26
  - **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)
27
  - **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)
28
  - **2022.09.04**: Add face upsampling `--face_upsample` for high-resolution AI-created face enhancement.
@@ -94,18 +95,30 @@ You can put the testing images in the `inputs/TestWhole` folder. If you would li
94
 
95
 
96
  #### Testing on Face Restoration:
97
- [Note] when comparing our model in your paper, please run the following command indicating `--has_aligned` (for cropped and aligned faces), 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.
 
 
98
  ```
99
  # For cropped and aligned faces
100
  python inference_codeformer.py --w 0.5 --has_aligned --test_path [input folder]
101
  ```
 
 
102
  ```
103
- # For the whole images
104
  # Add '--bg_upsampler realesrgan' to enhance the background regions with Real-ESRGAN
105
  # Add '--face_upsample' to further upsample restorated face with Real-ESRGAN
106
- python inference_codeformer.py --w 0.7 --test_path [input folder/image path]
 
 
 
 
 
 
 
107
  ```
108
 
 
109
  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.
110
 
111
  The results will be saved in the `results` folder.
 
23
 
24
  **[<font color=#d1585d>News</font>]**: :whale: *Due to copyright issues, we have to delay the release of the training code (expected by the end of this year). Please star and stay tuned for our future updates!*
25
  ### Update
26
+ - **2022.10.05**: Support video input `--test_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.
 
95
 
96
 
97
  #### Testing on Face Restoration:
98
+ [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.
99
+
100
+ 👨🏻 Face Restoration (cropped and aligned face)
101
  ```
102
  # For cropped and aligned faces
103
  python inference_codeformer.py --w 0.5 --has_aligned --test_path [input folder]
104
  ```
105
+
106
+ :framed_picture: Whole Image Enhancement
107
  ```
108
+ # For whole image
109
  # Add '--bg_upsampler realesrgan' to enhance the background regions with Real-ESRGAN
110
  # Add '--face_upsample' to further upsample restorated face with Real-ESRGAN
111
+ python inference_codeformer.py --w 1.0 --test_path [input folder/image path]
112
+ ```
113
+
114
+ :clapper: Video Enhancement
115
+ ```
116
+ # For video clips
117
+ # Set frame rate of saved video via '--save_video_fps 24'
118
+ python inference_codeformer.py --bg_upsampler realesrgan --face_upsample --w 0.7 --test_path [video path] --save_video_fps 24
119
  ```
120
 
121
+
122
  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.
123
 
124
  The results will be saved in the `results` folder.
inference_codeformer.py CHANGED
@@ -64,6 +64,7 @@ if __name__ == '__main__':
64
  parser.add_argument('--bg_upsampler', type=str, default='None', help='background upsampler. Optional: realesrgan')
65
  parser.add_argument('--face_upsample', action='store_true', help='face upsampler after enhancement.')
66
  parser.add_argument('--bg_tile', type=int, default=400, help='Tile size for background sampler. Default: 400')
 
67
 
68
  args = parser.parse_args()
69
 
@@ -72,15 +73,24 @@ if __name__ == '__main__':
72
  if args.test_path.endswith(('jpg', 'png')): # input single img path
73
  input_img_list = [args.test_path]
74
  result_root = f'results/test_img_{w}'
75
-
 
 
 
 
 
 
 
 
 
76
  else: # input img folder
77
  if args.test_path.endswith('/'): # solve when path ends with /
78
  args.test_path = args.test_path[:-1]
79
-
80
  input_img_list = sorted(glob.glob(os.path.join(args.test_path, '*.[jp][pn]g')))
81
  result_root = f'results/{os.path.basename(args.test_path)}_{w}'
82
 
83
-
84
  # ------------------ set up background upsampler ------------------
85
  if args.bg_upsampler == 'realesrgan':
86
  bg_upsampler = set_realesrgan()
@@ -128,15 +138,20 @@ if __name__ == '__main__':
128
  device=device)
129
 
130
  # -------------------- start to processing ---------------------
131
- # scan all the jpg and png images
132
- for img_path in input_img_list:
133
  # clean all the intermediate results to process the next image
134
  face_helper.clean_all()
135
 
136
- img_name = os.path.basename(img_path)
137
- print(f'Processing: {img_name}')
138
- basename, ext = os.path.splitext(img_name)
139
- img = cv2.imread(img_path, cv2.IMREAD_COLOR)
 
 
 
 
 
 
140
 
141
  if args.has_aligned:
142
  # the input faces are already cropped and aligned
@@ -208,4 +223,21 @@ if __name__ == '__main__':
208
  save_restore_path = os.path.join(result_root, 'final_results', f'{basename}.png')
209
  imwrite(restored_img, save_restore_path)
210
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
  print(f'\nAll results are saved in {result_root}')
 
64
  parser.add_argument('--bg_upsampler', type=str, default='None', help='background upsampler. Optional: realesrgan')
65
  parser.add_argument('--face_upsample', action='store_true', help='face upsampler after enhancement.')
66
  parser.add_argument('--bg_tile', type=int, default=400, help='Tile size for background sampler. Default: 400')
67
+ parser.add_argument('--save_video_fps', type=int, default=24, help='frame rate for saving video. Default: 24')
68
 
69
  args = parser.parse_args()
70
 
 
73
  if args.test_path.endswith(('jpg', 'png')): # input single img path
74
  input_img_list = [args.test_path]
75
  result_root = f'results/test_img_{w}'
76
+ elif args.test_path.endswith(('mp4', 'mov', 'avi')): # input video path
77
+ input_img_list = []
78
+ vidcap = cv2.VideoCapture(args.test_path)
79
+ success, image = vidcap.read()
80
+ while success:
81
+ input_img_list.append(image)
82
+ success, image = vidcap.read()
83
+ input_video = True
84
+ video_name = os.path.basename(args.test_path)[:-4]
85
+ result_root = f'results/{video_name}_{w}'
86
  else: # input img folder
87
  if args.test_path.endswith('/'): # solve when path ends with /
88
  args.test_path = args.test_path[:-1]
89
+ # scan all the jpg and png images
90
  input_img_list = sorted(glob.glob(os.path.join(args.test_path, '*.[jp][pn]g')))
91
  result_root = f'results/{os.path.basename(args.test_path)}_{w}'
92
 
93
+ test_img_num = len(input_img_list)
94
  # ------------------ set up background upsampler ------------------
95
  if args.bg_upsampler == 'realesrgan':
96
  bg_upsampler = set_realesrgan()
 
138
  device=device)
139
 
140
  # -------------------- start to processing ---------------------
141
+ for i, img_path in enumerate(input_img_list):
 
142
  # clean all the intermediate results to process the next image
143
  face_helper.clean_all()
144
 
145
+ if isinstance(img_path, str):
146
+ img_name = os.path.basename(img_path)
147
+ basename, ext = os.path.splitext(img_name)
148
+ print(f'[{i+1}/{test_img_num}] Processing: {img_name}')
149
+ img = cv2.imread(img_path, cv2.IMREAD_COLOR)
150
+ else: # for video processing
151
+ basename = str(i).zfill(6)
152
+ img_name = f'{video_name}_{basename}' if input_video else basename
153
+ print(f'[{i+1}/{test_img_num}] Processing: {img_name}')
154
+ img = img_path
155
 
156
  if args.has_aligned:
157
  # the input faces are already cropped and aligned
 
223
  save_restore_path = os.path.join(result_root, 'final_results', f'{basename}.png')
224
  imwrite(restored_img, save_restore_path)
225
 
226
+ # save enhanced video
227
+ if input_video:
228
+ # load images
229
+ video_frames = []
230
+ img_list = sorted(glob.glob(os.path.join(result_root, 'final_results', '*.[jp][pn]g')))
231
+ for img_path in img_list:
232
+ img = cv2.imread(img_path)
233
+ video_frames.append(img)
234
+ # write images to video
235
+ h, w = video_frames[0].shape[:2]
236
+ save_restore_path = os.path.join(result_root, f'{video_name}.mp4')
237
+ writer = cv2.VideoWriter(save_restore_path, cv2.VideoWriter_fourcc(*"mp4v"),
238
+ args.save_video_fps, (w, h))
239
+ for f in video_frames:
240
+ writer.write(f)
241
+ writer.release()
242
+
243
  print(f'\nAll results are saved in {result_root}')