classification이나 segmentation 작업을 위해 image augmentation을 하는 것은 그리 어려운 일이 아니다. 근데 object detection 영역으로 넘어오면 얘기가 달라진다. train image에 대해 augmentation을 진행할 때 ground truth도 같이 진행해줘야 하는데 이 과정이 까다롭기 때문이다. 예전에 잠깐 공부할 때는 flip, rotate, shift 등을 하나하나 직접 짜서 augmentation을 진행했었는데.. 우연히 회사 옆자리 연구원으로부터 imgaug 라이브러리를 알게되어 사용 방법을 정리하고자 한다.
imgaug ?
Image Augmentation을 위한 라이브러리다. 이곳에서 지원 augmentation 방법들을 확인할 수 있다.
정말이지 어마무시하게 많은 방법들을 지원해준다. 이걸 왜 진작 몰랐을까..
사진에서 볼 수 있듯이 train image뿐만 아니라 ground truth도 입력받아 같이 변형해주는 것을 확인할 수 있다. 간단한 사용법에 대해 알아보자.
코드1 - 한 개 변형 작업만 진행
import cv2
import numpy as np
import imgaug as ia
import imgaug.augmenters as iaa
img = cv2.imread('./test.jpg')
gt = np.loadtxt('./gt.txt', dtype = np.int, delimiter = ',')
input_img = img[np.newaxis, :, :, :]
bbox = [ia.BoundingBox(x1 = gt[0], y1 = gt[1], x2 = gt[2], y2 = gt[3])]
output_img, output_bbox = iaa.Affine(scale = 0.8)(images = input_img, bounding_boxes = bbox)
draw = output_bbox[0].draw_on_image(output_img[0], size = 2, color = [0,0,255])
res = np.hstack((img, draw))
cv2.imshow('res', res)
- [Line 7]
gt는 xmin, ymin, xmax, ymax 순으로 저장되어 있다. - [Line 10]
imgaug를 사용해 augmentation을 진행하려면 imgaug.BoundingBox( ) 형태로 ground truth를 만들어줘야한다. - [Line 12]
실제로 이미지 및 gt 변형이 진행되는 라인이다.
Affine 변환 중 원하는 작업 종류와 정도를 설정해주면 된다. - [Line 13~15]
iaa.Affine( ) 함수는 변형된 ground truth를 numpy array 형태가 아닌 imgaug.BoundingBox( )형태로 반환한다.
x1, y1, x2, y2를 직접 받아다가 결과를 그려줄 수 있지만
imgaug에서 기본으로 제공하는 draw_on_image( ) 함수를 사용해주면 변형된 image에 변형된 gt를 쉽게 그려줄 수 있다.
결과 이미지는 다음과 같다.
코드2 - 여러 개의 변형 작업 수행
import cv2
import numpy as np
import imgaug as ia
import imgaug.augmenters as iaa
img = cv2.imread('./test.jpg')
gt = np.loadtxt('./gt.txt', dtype = np.int, delimiter = ',')
input_img = img[np.newaxis, :, :, :]
bbox = [ia.BoundingBox(x1 = gt[0], y1 = gt[1], x2 = gt[2], y2 = gt[3])]
seq = iaa.Sequential([
iaa.Multiply((1.2, 1.5)),
iaa.Affine(
scale = (0.5, 0.7),
rotate = 45)])
aug_img, aug_bbox = seq(images = input_img, bounding_boxes = bbox)
draw = aug_bbox[0].draw_on_image(aug_img[0], size = 2, color = [0,0,255])
res = np.hstack((img, draw))
cv2.imshow('res', res)
- [Line 12]
여러 개의 변환 작업을 한 번에 설정해주고 싶은 경우 Line 12~16처럼 지정해주면 된다. - [Line 15]
scale 정도를 범위로 지정해주면 inference 할 때마다 범위 내의 값 중 하나로 random하게 진행된다.
결과 이미지는 다음과 같다.
사용 방식이 살짝 Keras의 ImageDataGenerator와 비슷한 느낌을 주는 imgaug에 대해 알아보았다. 사용이 굉장히 간편한 라이브러리이다. Object Detection 작업을 진행하는 분들이 data augmentation을 진행할 때 많이 사용하면 좋을 것 같다.
[ 참고 사이트 ]
https://github.com/aleju/imgaug
https://junyoung-jamong.github.io/machine/learning/2019/01/23/%EB%B0%94%EC%9A%B4%EB%94%A9%EB%B0%95%EC%8A%A4%EB%A5%BC-%ED%8F%AC%ED%95%A8%ED%95%9C-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%A6%9D%ED%8F%AD%EC%8B%9C%ED%82%A4%EA%B8%B0-with-imgaug.html
https://www.kaggle.com/andreagarritano/simple-data-augmentation-with-imgaug
'Python' 카테고리의 다른 글
Python으로 DICOM 파일 다루는 방법 (11) | 2021.08.31 |
---|---|
Python의 fileinput module로 파일 수정하는 방법 (1) | 2021.08.31 |
Python으로 지정 경로에 폴더 존재하는지 확인하고 없으면 폴더 생성하는 방법 (1) | 2021.08.31 |
Anaconda, Python, CMD, 명령어 정리 (0) | 2021.08.31 |
Python file 우클릭 시 context menu에 Anaconda 가상환경 idle 뜨게 하는 방법 (0) | 2021.08.31 |