본문 바로가기

부스트캠프 AI Tech/Pytorch

[11] image transform

PIL vs opencv


image 관련 작업을 할 때 이미지를 어떻게 불러오는지는 엄청 중요하다.
transform관련하여 torchvision이나 Albumentations 를 주로 이용하고 있는데
속도나 편함 측면에서 Albumentations 를 자주 쓰는 편이다.
Albumentations 라이브러리는 cv2로 읽고 RGB로 변환하여 input 하는 것을 권장한다.

PIL

  • RGB로 이미지 읽어옴
  • array화 필요

cv2

  • BGR로 이미지 읽어옴
  • Video capture와 같은 기능 지원이 잘 되어있음
  • PIL에는 없는 다양한 함수들 지원(PIL에 있는 거의 모든 기능이 OpenCV에 존재)
  • cv2 함수의 입력으로 numpy array를 넣어서 바로 사용가능(numpy array와의 호환성이 좋음)
  • numpy array 인덱싱을 이용해 이미지에 대한 전처리가 가능하기에 좀 더 자유롭게 이미지 전처리 가능

PIL vs cv2 차이 예시 코드

In [26]:

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import cv2

In [27]:

img = Image.open('thumb1.png')
img_ary = np.array(img) # PIL는 이미지로 가져와서 따로 array로 변환 필요
img_ary.shape # (338, 384, 3)
plt.imshow(img_ary) # RGB

Out[27]:

<matplotlib.image.AxesImage at 0x12873bb4308>

In [28]:

img_cv = cv2.imread('thumb1.png') # array로 읽어서 바로 imshow 가능
img_cv.shape # (338, 384, 3)
plt.imshow(img_cv) # BGR

Out[28]:

<matplotlib.image.AxesImage at 0x12873c352c8>

In [29]:

img_cv_rgb = cv2.cvtColor(img_cv, cv2.COLOR_BGR2RGB) # RGB로 변환
plt.imshow(img_cv_rgb)

Out[29]:

<matplotlib.image.AxesImage at 0x12873cb9208>

Albumentation을 이용한 이미지 augmentation


  • 속도 측면에서 좋고 보다 더 효율적이고 다양해서 개인적으로 torchvision 대신 사용한다.
  • 참고 (https://github.com/albumentations-team/albumentations)
  • cv2.imread -> cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
  • masks, bboxes, keypoints 같은 GT들도 같이 변환 가능

코드예시

import albumentations as A
import cv2

# Declare an augmentation pipeline
transform = A.Compose([
    A.RandomCrop(width=256, height=256),
    A.HorizontalFlip(p=0.5),
    A.RandomBrightnessContrast(p=0.2),
])

# Read an image with OpenCV and convert it to the RGB colorspace
image = cv2.imread("image.jpg")
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# Augment an image
transformed = transform(image=image)
transformed_image = transformed["image"]

masks, bboxes, keypoints

########################### segmentaton ###########################
augmentations = transform(image=image, mask=mask)

########################### object detection ###########################
transform = A.Compose([
    A.RandomCrop(width=450, height=450),
    A.HorizontalFlip(p=0.5),
    A.RandomBrightnessContrast(p=0.2),
], bbox_params=A.BboxParams(format='coco', min_area=1024, min_visibility=0.1, label_fields=['class_labels']))

transformed = transform(image=image, bboxes=bboxes, class_labels=class_labels)
transformed_image = transformed['image']
transformed_bboxes = transformed['bboxes']
transformed_class_labels = transformed['class_labels']

########################### keypoint estimation ########################
transform = A.Compose([
    A.RandomCrop(width=330, height=330),
    A.RandomBrightnessContrast(p=0.2),
], keypoint_params=A.KeypointParams(format='xy'))

transformed = transform(image=image, keypoints=keypoints)
transformed_image = transformed['image']
transformed_keypoints = transformed['keypoints']

ToTensorV2


Albumenations 을 pytorch에서 사용하려면
from albumentations.pytorch import ToTensor 하고
A.compose 마지막에 추가시켜준다.

transform = A.Compose([
    A.Normalize(),
    A.Resize(height=height, width=width),
    A.RandomResizedCrop(height=height, width=width, scale=(0.3, 1.0)),
    ToTensorV2()
])

이유가 뭘까요 ???
torch model이 받는 input shape를 고려해보면 (batch, channel, height, width) 입니다.
이미지를 읽을 때 opencv로 읽었기 때문에 (height, width, channel) 형태입니다.
batch는 dataloader에서 자동 변환되기 때문에 고려하지 않아도 되고 h,w,c 를 c,h,w 로
변환해주어야 하는데 ToTensorV2() 를 쓰면 array를 tensor로 바꿔주고 shape도 바꿔준다.

augmentation 눈으로 확인하기


streamlit 으로 만든 albumentation-demo 사이트 입니다.

https://albumentations-demo.herokuapp.com/

 

Streamlit

 

albumentations-demo.herokuapp.com

 

'부스트캠프 AI Tech > Pytorch' 카테고리의 다른 글

[13] Monitoring tool - Tensorboard  (0) 2022.01.24
[12] 전이학습 tansfer learning  (0) 2022.01.24
[10] Dataloader 의 기본요소  (0) 2022.01.22
[09] Dataset  (0) 2022.01.21
[08] backward 과정 이해하기  (0) 2022.01.20