stable diffusion webui로 생성한 이미지의 화질이 너무 낮아 활용하기 어려워졌다, 그냥 보기에는 화질이 괜찮아보이는데 시스템상으로 4MP이하라는 에러가 발생한것이다.....
이럴 때는 Python의 만능 이미지 처리기 opencv를 사용하도록하자
1. OpenCV 설치하기
pip install opencv-python
2. 이미지 불러오기
import cv2
#고칠 이미지를 불러오자
#이미지 파일 경로설정
img_path='./경로/이미지 이름.png'
#이미지를 불러올때의 option값 생략하면 자동으로 1을 선택한다.
option = 1
target_img=cv2.imread(img_path, option)
Option값은 크게 3가지가 있다.
1 : color(BGR) 읽기, 생략하면 1로 인식
0 : gray-scale(회색) 읽기
-1 : color(BGR) + alpha channel(투명도) 까지 포함하는 읽기
불러온 target_img를 사용해서 이미지 화질을 좋게 바꿔보자.
단순히 화질을 좋아지게 하는것말고도 Tensorflow나, Pytorch의 DNN을 활용하여, 특정 이미지 감지 / AI 이미지 판독과 같은 코드들도 사용이 가능하다.
https://docs.opencv.org/4.x/d2/d58/tutorial_table_of_content_dnn.html
3. 업스케일링을 위한 딥러닝 모델 불러오기
아래 깃허브 주소로 가서 원하는 업스케일 화질을 선택하여 다운로드 한다.
https://github.com/Saafke/EDSR_Tensorflow/tree/master/models
필자는 EDSR_x3.pb를 사용할것이다.
import cv2
from cv2 import dnn_superres
#업스케일 도구 가져오기
sr = dnn_superres.DnnSuperResImpl_create()
#모델 읽어오기
path = 'EDSR_x3.pb'
sr.readModel(path)
#모델의 이미지 스케일 지정하기(x3일때는 3, EDSR_x4.pb일때는 4를 입력하면 된다.)
sr.setModel('edsr', 3)
만약 from cv2 import dnn_superres를 실행할 때
ImportError: cannot import name 'dnn_superres' from 'cv2' (/Users/.../opt/anaconda3/envs/DLLGE/lib/python3.8/site-packages/cv2/__init__.py) |
에러가 발생한다면, pip install opencv-contrib-python 를 실행하면 된다.
만일 module 'cv2.cv2' has no attribute 'dnn_superres'와 같은 에러가 발생한다면,
pip uninstall opencv-python 로 지워주고 다시 실행해주자, opencv-python과 opencv-contrib-python이 충돌하는 것 같다.
만일 본인이 CUDA가 있다면 사용설정을 해줘야지만 CUDA활용이 가능하다.
sr.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
sr.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)
CUDA란??
https://mrnoobiest.tistory.com/584
아까 불러왔던 target_image를 사용하자.
upscaled = sr.upsample(target_image)
cv2.imwrite('./Upscaled_Test.png', upscaled)
이렇게 하면 아래와 같이 업스케일링된 이미지가 생성된다. 대략 12초 소요
전체 코드(EDSR_X3.pb 사용시)
import cv2
from cv2 import dnn_superres
target_image=cv2.imread('./taget_image.png')
sr = dnn_superres.DnnSuperResImpl_create()
path = './EDSR_x3.pb'
sr.readModel(path)
sr.setModel('edsr', 3)
upscaled = sr.upsample(target_image)
cv2.imwrite('./Upscaled_Test.png', upscaled)
여기서 끝나면 재미없으니, 특정 폴더를 선택하면 자동으로 해당 폴더내의 모든 이미지 파일들을 업스케일링하는 코드로 개조해보자.
4. 코드 개조하기
4-1) 특정 폴더내에 있는 이미지 확장자 파일명 모두 가져오기
import os
def get_image_files(folder_path):
image_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp'] # 이미지 파일 확장자 리스트
image_files = []
for file in os.listdir(folder_path):
if os.path.isfile(os.path.join(folder_path, file)):
if any(file.lower().endswith(ext) for ext in image_extensions):
image_files.append(file)
return image_files
# 특정 폴더 경로 지정
folder_path = './경로명'
# 이미지 파일 리스트 추출
image_files = get_image_files(folder_path)
# 이미지 파일 리스트 출력
for file in image_files:
print(file)
4-2) 업스케일링 함수화 하기
def upscale_image(file_name,output_folder_name):
import cv2
from cv2 import dnn_superres
target_image=cv2.imread('./{}'.format(file_name))
sr = dnn_superres.DnnSuperResImpl_create()
path = './EDSR_x3.pb'
sr.readModel(path)
sr.setModel('edsr', 3)
upscaled = sr.upsample(target_image)
#output이 없으면 생성하는 코드
isExist = os.path.exists('./{}'.format(output_folder_name))
if not isExist:
os.mkdir('./{}'.format(output_folder_name))
try:
cv2.imwrite('./{}/Upscaled_{}'.format(output_folder_name,file_name), upscaled)
result='done'
except Exception as e:
result=e
return result
4-3) image_files와 upscale_image(file_name,output_folder_name)를 사용해서 이미지 일괄 업스케일링 하기
for image in image_files:
output_folder_name='결과를 출력한 폴더명 지정하기'
result=upscale_image(image,output_folder_name)
다음엔 stable diffuision을 활용해서 업스케일링하는 방법을 알아보자.
끝!