Hôm nay, mình sẽ hướng dẫn các bạn Phục hồi ảnh cũ với Deep Learning. Trong bài viết này, chúng ta chỉ tập trung vào ứng dụng của Deep Learning trong việc làm sống lại các bức ảnh đã cũ hay hư hỏng. Sẽ không là vấn đề lớn nếu bạn chưa hiểu code. Chúng ta cứ từ từ tìm hiểu nhé.
Bring Old Photos Back To Life – Old Photo Restoration
Đầu tiên, chúng ta tìm hiểu sơ qua về “Bring Old Photos Back To Life” nhé.
“Bring Old Photos Back To Life” là một model khôi phục ảnh cũ mã nguồn mở, được giới thiệu bởi Microsoft. Mô hình khôi phục hình ảnh dựa trên Deep Learning này có các tính năng sau:
- Denoising
- Tone Readjustment
- Face Enhancement
- Physical Damage Restoration
- Scratches
- Brown spots
- Food marks
Mặc dù đã có nhiều models trước đây, nhưng điều làm cho nó trở nên độc đáo là kết quả đáng ngạc nhiên của nó. Kết quả của mô hình này đã vượt qua tất cả các mô hình đã có trước đây.
Phục hồi ảnh cũ với Deep Learning
Bây giờ đã đến lúc xem cách chúng ta có thể sử dụng model trên để khôi phục ảnh thế nào. Chúng ta sẽ sử dụng Google Colab vì nó cung cấp GPU miễn phí sẽ cần nó trong dự án của mình.
Các bạn nhớ chọn Runtime Type là Python3 và Hardware Accelerator là GPU nhé.
Đầu tiên, chúng ta sẽ clone “Bring Old Photos Back To Life” từ Github và đặt tên thư mục tên là photo_restoration.
1 |
!git clone https://github.com/microsoft/Bringing-Old-Photos-Back-to-Life.git photo_restoration |
Cài đặt môi trường
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# pull the syncBN repo %cd photo_restoration/Face_Enhancement/models/networks !git clone https://github.com/vacancy/Synchronized-BatchNorm-PyTorch !cp -rf Synchronized-BatchNorm-PyTorch/sync_batchnorm . %cd ../../../ %cd Global/detection_models !git clone https://github.com/vacancy/Synchronized-BatchNorm-PyTorch !cp -rf Synchronized-BatchNorm-PyTorch/sync_batchnorm . %cd ../../ # download the landmark detection model %cd Face_Detection/ !wget http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2 !bzip2 -d shape_predictor_68_face_landmarks.dat.bz2 %cd ../ # download the pretrained model %cd Face_Enhancement/ !wget https://facevc.blob.core.windows.net/zhanbo/old_photo/pretrain/Face_Enhancement/checkpoints.zip !unzip checkpoints.zip %cd ../ %cd Global/ !wget https://facevc.blob.core.windows.net/zhanbo/old_photo/pretrain/Global/checkpoints.zip !unzip checkpoints.zip %cd ../ |
1 |
! pip install -r requirements.txt |
Chạy code phục hồi ảnh cũ (chế độ cơ bản)
1 2 3 4 5 6 7 8 9 10 11 12 |
%cd /content/photo_restoration/ input_folder = "test_images/old" output_folder = "output" import os basepath = os.getcwd() input_path = os.path.join(basepath, input_folder) output_path = os.path.join(basepath, output_folder) os.mkdir(output_path) !python run.py --input_folder /content/photo_restoration/test_images/old --output_folder /content/photo_restoration/output/ --GPU 0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
import io import IPython.display import numpy as np import PIL.Image def imshow(a, format='png', jpeg_fallback=True): a = np.asarray(a, dtype=np.uint8) data = io.BytesIO() PIL.Image.fromarray(a).save(data, format) im_data = data.getvalue() try: disp = IPython.display.display(IPython.display.Image(im_data)) except IOError: if jpeg_fallback and format != 'jpeg': print(('Warning: image was too large to display in format "{}"; ' 'trying jpeg instead.').format(format)) return imshow(a, format='jpeg') else: raise return disp def make_grid(I1, I2, resize=True): I1 = np.asarray(I1) H, W = I1.shape[0], I1.shape[1] if I1.ndim >= 3: I2 = np.asarray(I2.resize((W,H))) I_combine = np.zeros((H,W*2,3)) I_combine[:,:W,:] = I1[:,:,:3] I_combine[:,W:,:] = I2[:,:,:3] else: I2 = np.asarray(I2.resize((W,H)).convert('L')) I_combine = np.zeros((H,W*2)) I_combine[:,:W] = I1[:,:] I_combine[:,W:] = I2[:,:] I_combine = PIL.Image.fromarray(np.uint8(I_combine)) W_base = 600 if resize: ratio = W_base / (W*2) H_new = int(H * ratio) I_combine = I_combine.resize((W_base, H_new), PIL.Image.LANCZOS) return I_combine |
1 2 3 4 5 6 7 8 9 |
filenames = os.listdir(os.path.join(input_path)) filenames.sort() for filename in filenames: print(filename) image_original = PIL.Image.open(os.path.join(input_path, filename)) image_restore = PIL.Image.open(os.path.join(output_path, 'final_output', filename)) display(make_grid(image_original, image_restore)) |
Khôi phục ảnh bị trầy xước
1 2 |
!rm -rf /content/photo_restoration/output/* !python run.py --input_folder /content/photo_restoration/test_images/old_w_scratch/ --output_folder /content/photo_restoration/output/ --GPU 0 --with_scratch |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
input_folder = "test_images/old_w_scratch" output_folder = "output" input_path = os.path.join(basepath, input_folder) output_path = os.path.join(basepath, output_folder) filenames = os.listdir(os.path.join(input_path)) filenames.sort() for filename in filenames: print(filename) image_original = PIL.Image.open(os.path.join(input_path, filename)) image_restore = PIL.Image.open(os.path.join(output_path, 'final_output', filename)) display(make_grid(image_original, image_restore)) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
from google.colab import files import shutil upload_path = os.path.join(basepath, "test_images", "upload") upload_output_path = os.path.join(basepath, "upload_output") if os.path.isdir(upload_output_path): shutil.rmtree(upload_output_path) if os.path.isdir(upload_path): shutil.rmtree(upload_path) os.mkdir(upload_output_path) os.mkdir(upload_path) uploaded = files.upload() for filename in uploaded.keys(): shutil.move(os.path.join(basepath, filename), os.path.join(upload_path, filename)) |
1 2 |
# if your image doesn't have scractches, then remove "--with_scratch" from the end of below line !python run.py --input_folder /content/photo_restoration/test_images/upload --output_folder /content/photo_restoration/upload_output --GPU 0 --with_scratch |
1 2 3 4 5 6 7 8 9 10 11 12 |
filenames_upload = os.listdir(os.path.join(upload_path)) filenames_upload.sort() filenames_upload_output = os.listdir(os.path.join(upload_output_path, "final_output")) filenames_upload_output.sort() for filename, filename_output in zip(filenames_upload, filenames_upload_output): image_original = PIL.Image.open(os.path.join(upload_path, filename)) image_restore = PIL.Image.open(os.path.join(upload_output_path, "final_output", filename_output)) display(make_grid(image_original, image_restore)) print("") |

Cuối cùng, chúng ta có thể download tất cả hình ảnh về máy tính của mình.
1 2 3 4 |
output_folder = os.path.join(upload_output_path, "final_output") print(output_folder) os.system(f"zip -r -j download.zip {output_folder}/*") files.download("download.zip") |
Chúc các bạn thành công. Đừng quên theo dõi các bài viết tiếp theo từ Ngô Tôn .IT trong series Tự học và phát triển ứng dụng thực tế AI, ML, DL, DS
Leave a Reply