Intro
Vision 분야에서 Deep learning 모델을 학습 시키려면 많은 양의 Image 데이터가 필요하다.
이때, 우리가 가질 수 있는 Image 데이터의 수에는 사실상 한계가 존재하기 마련인데- 이를 조금이나마 극복할 수 있게 도와주는 좋은 툴이 존재한다.
이름하여 `Albumentation` !!!
CropAndPad
오늘은 그중에서도 `CropAndPad`라는 패키지를 살펴보려고 한다.
내가 직면했던 문제점은, 모델을 학습시킨 이미지의 비율(1:1 이미지로 학습됨)과 모델 성능을 평가하려는 이미지의 비율(16:9 사진으로 평가)가 달랐다는 것에서부터 출발했다.
자주 발생하는 이슈인지는 모르겠으나, 모델을 학습시킨 이미지들의 경우 (이미 엄청난 품이 들어간)라벨링이 되어 있기 때문에....
이후에 테스트하고자 하는 이미지를 다양한 출처로부터 (DSRL 카메라로 찍었다든지, 다른곳에서 퍼왔다든지, 등등) 모았을 때 문제가 생길 것 같다.
비율이 다른게 뭐 어때서?
라는 질문이 들 수 있는데,
현재 가지고 있는 딥러닝 모델이 아이패드와 연동되어 있기 때문에- (경량화된 모델 deploy하시는 팀으로부터)
16:9의 평가 데이터셋을 넣어 줄 경우에 자동으로 1:1 변환이(종방향압축으로 이미지 비율이 파괴)되어 들어간다는 이슈를 받았다.
그래서 평가 데이터셋의 위아래에 패딩을 넣어주어, 1:1 비율의 이미지를 만들기로 했던 것.
그래서 다시 CropAndPad
관련 함수는 여기에 들어가면 decription을 자세히 읽어볼 수 있다.
크게 Crop(기존 사진에 있는 픽셀들을 잘라서 날려버리기)/Pad(기존 사진에 없던 픽셀을 추가하기) 두가지 기능이 있다.
매우 헷갈리므로 함수에 들어가는 parameter 들을 하나씩 읽어보겠다.
여기부터 지겨움주의, BUT 찬찬히 읽어보면 금방 이해 가능
Parameters
1) `px` (int or tuple)
`px`와 `percent`변수는 둘 중 하나만 정의되어야 한다. 입력된 수만큼 pixel rows를, 이미지의 각 side마다 Crop/Pad를 해준다. 이때 음수로 입력하면 Crop을, 양수로 입력하면 Pad를. Default값이 None이기 때문에 입력하지 않을 경우 아무 일도 일어나지 않는다. 정수로 입력될 경우 정확히 그 갯수 만큼의 pixel들이 처리되고, 정수 인자를 갖는 (a, b)의 튜플이 입력될 경우 범위[a, b] 내의 정수 하나를 random하게 뽑아 그 갯수만큼의 pixel들이 처리된다. 만약 `sample_independently` 변수가 False일 경우, 하나의 값으로만 패딩된다(예, 0값으로만 패딩될 경우 모든 패딩은 검정색). 만약 4개의 int 요소를 가진 tuple이 입력될 경우, (top, right, bottom, left)에 각각 Crop 또는 Pad될 pixel 갯수를 의미한다. 4개의 각 요소는 정수 또는 tuple로 받을 수 있다.
2) `percent` (float or tuple)
입력된 (높이와 너비) 비율만큼의 pixel rows를 이미지의 각 side마다 Crop/Pad 해준다. (예를들어, -0.1로 입력되었을 경우, top, right, bottom, left 에서 각각 이미지의 높이의 10%에 해당하는 pixel들을 Crop 해줄 것이다. 입력될 수 있는 값은 (-1.0, inf) 사이이다. `px`와 `percent`변수는 둘 중 하나만 정의되어야 한다. Default값이 None이기 때문에 입력하지 않을 경우 아무 일도 일어나지 않는다. float 인자를 갖는 (a, b)의 튜플이 입력될 경우 범위[a, b] 내의 비율 하나를 random하게 뽑아 그 비율만큼의 pixel들이 처리된다. 만약 `sample_independently` 변수가 False일 경우, 하나의 값으로만 패딩된다(예, 0값으로만 패딩될 경우 모든 패딩은 검정색). 만약 4개의 float 요소를 가진 tuple이 입력될 경우, (top, right, bottom, left)에 각각 Crop 또는 Pad될 pixel 비율들을 의미한다. 4개의 각 요소는 float 또는 tuple로 받을 수 있다.
3) `pad_mode` (int)
OpenCV에서 지정한 border mode를 입력하면 된다.
자세한 설명은 여기서는 생략하지만, 모든 픽셀을 하나의 값(색)으로 padding하고 싶다면 `0`으로(BORDER_CONSTANT) 설정하면 된다.
4) `pad_cval` (number, Sequence[number]) 발음주의
`pad_mode`를 `0(BOARDER_CONSTANT`로 설정할 경우 사용하는 변수이다. 숫자로 입력될 경우, 그 값이 사용된다(예, 114가 입력되면 gray로). tuple로 입력할 경우 random 기능을 위함이다(사용할 일이 많지 않으므로 이정도만 설명하려고 한다).
5) `pad_cval_mask`(number, Sequence[number])
`pad_cval`과 똑같은데, mask만을 위함이라고 한다. 추가 설명을 덧붙이자면, Albumentation transform의 인자로 나중에 image와 mask를 둘 다 넣어주는 경우가 있는데, 이때 image와 mask에 다른 padding 처리를 하고 싶을 경우 사용하나보다.
6) `keep_size` (bool)
Cropping이나 Padding을 할 경우, image의 원래 height와 width가 변할 것을 고려해서 만들어진 변수. 만약 `keep_size`가 True라면, Crop/Pad 처리 된 이미지가에 `Resize`라는 또 다른 Albumentation transform 함수가 자동으로 적용되어 크기를 유지해 준다고 한다. 나의 경우 애초의 목적이 이미지 사이즈를 변경하는 것이기 때문에, 이 변수만은 꼭 False로 설정해 주어야 한다.
7) `sample_independently` (bool)
False로 설정될 경우 하나의 값으로만 패딩된다(예, 0값으로만 패딩될 경우 모든 패딩은 검정색). True일 경우, 4개의 값이 각각 top, right, bottom, left에 패딩된다.
8) `interpolation` (OpenCV flag)
OpenCV에서 지정한 interpolation algorithm을 선택하여 입력하면 된다. 다음 중 하나의 값이 입력되어야 한다.
위 링크에서 소개된 flag중 0, 1, 2, 3, 4, 7만 적용 가능하며(7, 8, 16은 Albumentation에서 지원하지 않는듯) Defalt는 `0(INTER_NEAREST`이다.
Codes
아래의 flow에 따라, 기존에 512x512 였던 이미지를 transform 하려고 한다.
1) Resize : 300x533 (9:16으로 이미지를 종방향 압축)
2) CenterCrop : 300x168 (16:9로 이미지를 자름, 잘린 나머지 픽셀은 버림)
3) Padding : 300x300 (1:1로 이미지의 위아래에 패딩을 넣어줌, 새로 검정 픽셀을 추가)
이때, 이미지의 top과 bottom에 각각 padding을 해주어야 하는 pixel rows는 각각 (300-168)/2=66 이므로 아래와 같이 `px` 변수에 (66, 0, 66, 0)이라는 튜플을 넣어 준다. Constant한 padding을 할 것이므로 `pad_mode`는 BORDER_CONSTANT를, 검정색 패딩을 할 것이므로 `pad_cval`은 0 값을, 패딩 후 이미지의 크기가 변해야 하므로`keep_size`는 False를, 하나의 값으로만 패딩을 진행할 것이므로 `sample_independently`는 False를, 모든 이미지에 대하여 적용할 것이므로 `p(probability)`는 1.0을 넣어준다.
transform = A.Compose([ # TODO;
A.Resize(width=300, height=533, interpolation=3),
A.CenterCrop(width=300,height=168, p=1),
A.CropAndPad(px=(66, 0, 66, 0), pad_mode=BORDER_CONSTANT, pad_cval=0,
keep_size=False, sample_independently=False, p=1.0)
],
bbox_params = A.BboxParams(format='coco', min_visibility=0, label_fields=['category_ids']),
)
과정에 따라 변환된 이미지들은 아래와 같다.
완성!!
'Tech > Computer Vision' 카테고리의 다른 글
[Open CV] Object detection을 위한 데이터 시각화 (2) : bounding box와 image 함께 보기 (0) | 2022.04.26 |
---|---|
[COCO Fifty One] Object detection을 위한 데이터 시각화 (1) : annotation 파일과 image 함께 보기 (0) | 2022.04.26 |