이것저것 기록

[DL, 전처리] 정사각형으로 이미지 사이즈 맞추기, 자르기 본문

Data Science/ML & DL

[DL, 전처리] 정사각형으로 이미지 사이즈 맞추기, 자르기

anweh 2020. 9. 22. 19:53

딥러닝의 단점이라고 해야하나... 조금 귀찮은 점이 있다면 모든 입력데이터의 사이즈가 동일해야하다는 것이다. 

그리고 대부분의 모델이 정사각형 이미지 파일을 입력데이터로 쓴다.

그래서 개인 데이터를 모은 후엔 꼭 이미지 파일 크기를 정사각형으로 맞춰줘야한다.

 

1. 성규 데이터셋

성규가 20명

 

덕업일체의 표본ㅋㅋㅋ;; 

아무튼 내 개인 데이터셋은 20장의 인피니트 성규 이미지다. 

보다시피 정사각형도 아니고, 각각의 파일 별로 크기도 다르다. 

 

 

2. Resize & Crop 

import os,sys
from PIL import Image


size = 256, 256 #바꾸고 싶은 사이즈
path = "C:/Users/user/Desktop/normal2retro/A/" #이미지 경로
modified_path = "C:/Users/user/Desktop/normal2retro/A/resize/" #resize된 이미지가 저장될 경로
os.chdir(path)



def resize_and_crop(img_path, modified_path, size, crop_type='middle'):
    
    files = os.listdir(img_path)
    
    for file in files: 
        
        name = str(file)
        os.chdir(img_path)
        img = Image.open(file)
        img_ratio = img.size[0] / float(img.size[1])
        ratio = size[0] / float(size[1])
        
        if ratio > img_ratio:
            img = img.resize((size[0], int(round(size[0] * img.size[1] / img.size[0]))),
                Image.ANTIALIAS)     
            if crop_type == 'top':
                box = (0, 0, img.size[0], size[1])
            elif crop_type == 'middle':
                box = (0, int(round((img.size[1] - size[1]) / 2)), img.size[0],
                    int(round((img.size[1] + size[1]) / 2)))
            elif crop_type == 'bottom':
                box = (0, img.size[1] - size[1], img.size[0], img.size[1])
            else :
                raise ValueError('ERROR: invalid value for crop_type')
            img = img.crop(box)
            
        elif ratio < img_ratio:
            img = img.resize((int(round(size[1] * img.size[0] / img.size[1])), size[1]),
                Image.ANTIALIAS)
            if crop_type == 'top':
                box = (0, 0, size[0], img.size[1])
            elif crop_type == 'middle':
                box = (int(round((img.size[0] - size[0]) / 2)), 0,
                    int(round((img.size[0] + size[0]) / 2)), img.size[1])
            elif crop_type == 'bottom':
                box = (img.size[0] - size[0], 0, img.size[0], img.size[1])
            else :
                raise ValueError('ERROR: invalid value for crop_type')
            img = img.crop(box)
            
        else :
            img = img.resize((size[0], size[1]), Image.ANTIALIAS)
            
        os.chdir(modified_path)
        img.save(name, "PNG")


resize_and_crop(path, modified_path, size)

해당 코드는 gist.github.com/sigilioso/2957026 를 참고했다. 

찾아보니까 비율을 유지한 채 리사이징 해서, 빈 공간에 흰 픽셀을 채워주는 코드도 있었다.

하지만 나는 꽉꽉 찬게 좋기 때문에.. 과감히 남는 부분은 크롭하기로 했다. 

 

 

3. 실행 결과

resize된 성규가 20명

middle로 크롭하다 보니 성규 얼굴이 잘린 파일도 몇 개 있다 ㅠㅠ

주의할 점은! 리사이즈한 이미지가 저장될 폴더를 미리 만들어놓고 실행해야한다. 

 

그리고 중간에 

PermissionError

이런 에러가 여러 번 떴었다. 찾아보니까 

 

1) 파일을 오픈할 수 있는 권한이 없을 때

2) 파일이 아니라 폴더를 지정했을 때

3) 파일이 없을 때

 

이런 에러가 발생한다는데, 3개중 어느 것에도 해당되지 않았다.

심지어 해당 에러가 발생했음에도 코드는 잘 실행됐고, 리사이징 성규(?)도 생성 돼 있었다.

리사이즈 이미지가 만들어진 줄 모르고 에러 고치려고 구글링 삼매경;;;; 

 

 

 

Comments