파이썬 이미지의 얼굴 품질 개선하기(GFPGAN, REALESRGAN)
파이썬에서 GFPGAN과 REALESRGAN을 이용해 이미지에 있는 얼굴의 품질을 개선하고 업스케일링 할 수 있습니다. 이를 이용해 화질이 안 좋은 이미지의 얼굴을 선명하게 만들수 있습니다. 화질이 안 좋은 이미지와 insightface를 이용해 얼굴을 바꾼 이미지에 적용해보겠습니다.
목차
모델 다운로드
GFPGAN, REALESRGAN 모델을 다운로드 받고 작업할 폴더를 만들어 넣어줍니다.
GFPGAN 다운로드 링크 : https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.4.pth
REALESRGAN 다운로드 링크 : https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-x4v3.pth
각각의 깃허브에서 다른 버전의 모델을 다운받을 수 있고 모델에 대한 자세한 내용을 볼 수 있습니다.
리눅스나 코랩의 경우 wget을 이용해 다운로드 받을 수 있습니다. 작업폴더의 경로에서 아래 명령을 실행해줍니다.
wget https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.4.pth -O GFPGANv1.4.pth
wget https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-x4v3.pth -O realesr-general-x4v3.pth
라이브러리 설치
우선 이미지를 다루기 위한 라이브러리 opencv, pillow 와 파이토치 라이브러리 torch, torchvision이 필요합니다.
pip install pillow opencv-python
torch, torchvision의 경우 https://pytorch.kr/get-started/locally/ 이 링크에서 환경에 맞는 pip 명령어를 볼 수 있습니다.
이제 GFPGAN과 REALESRGAN을 사용하기 위한 라이브러리를 설치하겠습니다.
pip install basicsr facexlib gfpgan realesrgan
얼굴이 포함된 이미지의 품질 개선하기 (얼굴, 배경)
이제 파이썬으로 이미지와 모델을 불러와 얼굴 품질을 개선해보겠습니다. 먼저 라이브러리를 불러옵니다.
from PIL import Image
import cv2
from basicsr.archs.srvgg_arch import SRVGGNetCompact
from gfpgan.utils import GFPGANer
from realesrgan.utils import RealESRGANer
import torch
만약 No module named ‘torchvision.transforms.functional_tensor’ 라는 에러가 나온다면 오류가 발생한 파일을 수정해줘야 합니다.

코랩의 경우 /usr/local/lib/python3.10/dist-packages/basicsr/data/degradations.py 파일에서 오류가 생겼다고 표시해주고 있습니다. 클릭해주면 화면의 오른쪽에서 파일을 수정할 수 있고 8번째 줄 from torchvision.transforms.functional_tensor import rgb_to_grayscale 의 functional_tensor를 functional로 바꿔주면 됩니다.
model = SRVGGNetCompact(num_in_ch=3, num_out_ch=3, num_feat=64, num_conv=32, upscale=4, act_type='prelu')
half = True if torch.cuda.is_available() else False
upsampler = RealESRGANer(scale=4, model_path='realesr-general-x4v3.pth', model=model, tile=0, tile_pad=10, pre_pad=0, half=half)
face_enhancer = GFPGANer(model_path='GFPGANv1.4.pth', upscale=2, arch='clean', channel_multiplier=2, bg_upsampler=upsampler)
REALESRGAN은 배경을 포함해 전체적인 화질을 개선하고 업스케일링합니다. SRVGGNetCompact의 인수는 신경망과 관련된 값들입니다.
- num_in_ch : 입력 채널 수로 컬러이미지면 3 흑백이면 1이 됩니다
- num_out_ch : 출력 채널 수로 컬러이미지면 3 흑백이면 1이 됩니다
- num_feat : 피쳐맵의 수
- num_conv: 컨볼루션 레이어의 수
- upscale: 업스케일링 배수
- act_type: 활성화함수 종류
SRVGGNetCompact에 대한 코드는 https://github.com/xinntao/Real-ESRGAN/blob/master/realesrgan/archs/srvgg_arch.py 에 있습니다.
cuda gpu를 이용한다면 half를 True로 설정합니다. RealESRGANer의 인수를 보겠습니다.
- upscale: 업스케일링 배수로 SRVGGNetCompact의 upscale 값과 같아야 합니다
- model_path: realesrgan 모델의 경로를 넣어줍니다
- model: SRVGGNetCompact로 생성한 model을 넣어줍니다
- tile: 0이면 이미지 전체를 한번에 처리하고 0이 아니면 값에 따라 이미지를 나눠서 처리합니다
- tile_pad: 타일로 나눠진 이미지에 패딩을 추가합니다
- pre_pad: 이미지를 타일로 나누기전에 패딩을 추가합니다
- half: True면 모델의 가중치의 소수 정확도를 낮춰서 계산합니다. 속도가 빠르고 메모리도 절약하지만 성능이 약간 저하될수 있습니다
RealESRGANer에 대한 코드는 https://github.com/xinntao/Real-ESRGAN/blob/master/realesrgan/utils.py에 있습니다.
GFPGAN은 얼굴을 복원하고 화질을 개선합니다.
- model_path: GFPGAN 모델의 경로를 넣어줍니다
- upscale: 최종업스케일링 배수
- arch: 모델의 아키텍쳐를 선택하는데 clean, original, RestoreFormer 중에 하나를 넣어줍니다
- channel_multiplier : 채널 배수
- bg_upsampler: 배경 업샘플러로 RealESRGANer으로 만든 업샘플러를 넣어줍니다
이제 GFPGANer를 이미지에 사용해보겠습니다. opencv로 이미지를 불러와서
img2 = cv2.imread('sq.webp')
GFPGANer를 사용합니다
cropped_faces, restored_faces, restored_img = face_enhancer.enhance(img2, has_aligned=False, only_center_face=False, paste_back=True)
- has_aligned: 얼굴이 이미 정렬되었는지에 대한 여부
- only_center_face: 가운데 얼굴만 작업을 수행하는지에 대한 여부
- paste_back: 최종결과로 전체 이미지를 리턴할지 여부
- 리턴 값 : 크롭된 얼굴들에 대한 리스트 , 복원(화질개선)된 얼굴들에 대한 리스트, 복원(화질개선)된 이미지
GFPGANer에 대한 코드는 https://github.com/TencentARC/GFPGAN/blob/master/gfpgan/utils.py 에 있습니다.
3가지의 리턴 값들을 출력해보겠습니다. 첫번째와 두번째 리턴 값은 얼굴 이미지에 대한 리스트인데 0번 인덱스를 비교하겠습니다.
temp1 = cv2.cvtColor(cropped_faces[0], cv2.COLOR_BGR2RGB)
rimg1 = Image.fromarray(temp1)
display(rimg1)
temp2 = cv2.cvtColor(restored_faces[0], cv2.COLOR_BGR2RGB)
rimg2 = Image.fromarray(temp2)
display(rimg2)


temp3 = cv2.cvtColor(restored_img, cv2.COLOR_BGR2RGB)
rimg3 = Image.fromarray(temp3)
display(rimg3)


얼굴 합성 후 품질 개선
저번 글에서 insightface를 이용해 얼굴 합성을 했습니다. 얼굴 합성 후 GFPGAN을 이용해 화질을 개선할 수 있습니다. 내용은 이 부분에서 연결됩니다. 얼굴이 합성된 이미지의 품질을 개선하기 위해서는 swapper.get을 통해 나온 결과를 face_enhancer.enhance의 이미지 부분에 넣어주면 됩니다.
result = swapper.get(img2, faces2[1], random_face, paste_back=True)
temp = cv2.cvtColor(result, cv2.COLOR_BGR2RGB)
rimg = Image.fromarray(temp)
display(rimg)
저번에 만들었던 함수를 약간 바꿔서 사용하겠습니다.
def faceswap2(img,faces1,faces2,l):
for t in l:
img = swapper.get(img, faces1[t[0]], faces2[t[1]], paste_back=True)
return img
result = faceswap2(img2,faces2,faces1,[(6,2),(0,2),(4,1),(5,1),(1,0),(2,0),(3,0),(7,0)])
_,_,restored_img = face_enhancer.enhance(result, has_aligned=False, only_center_face=False, paste_back=True)
temp4 = cv2.cvtColor(restored_img, cv2.COLOR_BGR2RGB)
rimg4 = Image.fromarray(temp4)
display(rimg4)


이 방법으로도 이미지가 맘에 안들면 인페인팅을 이용해 이미지의 특정 부분을 새로 그려서 결과를 개선할 수 있습니다.
얼굴합성, gfpgan사용과 관련된 주피터노트북파일입니다.