Programming/OpenCV

OpenCV를 이용한 Image augmentation 구현

시작

언제나 데이터가 많으면 좋겠지만 현실에서 대용량 데이터셋 구축은 쉽지 않다. (끝없는 노가다...)

데이터를 많이 모으는것도 힘든데, 양질의 데이터를 모으는것도 참 쉽지 않다는것을 느꼈다.

한정된 데이터셋을 augmentation 기법을 활용해 데이터셋의 다양성을 증가시켜줄수 있다.

OpenCV를 이용해 Image augmentation을 구현 해보자

[구현 항목]

1. Rotate

2. Shift

3. Flip

4. brightness

5. Contrast

 

 

data_augmentation
In [1]:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import cv2
import glob
import random
In [2]:
def brightness(gray, val):
    #gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    brightness = int(random.uniform(-val, val))
    if brightness > 0:
        gray = gray + brightness
    else:
        gray = gray - brightness
    gray = np.clip(gray, 10, 255)
    return gray
In [3]:
def contrast(gray, min_val, max_val):
    #gray = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
    alpha = int(random.uniform(min_val, max_val)) # Contrast control
    adjusted = cv2.convertScaleAbs(gray, alpha=alpha)
    return adjusted
In [4]:
def fill(img, h, w):
    img = cv2.resize(img, (h, w), cv2.INTER_CUBIC)
    return img
In [5]:
def rotation(img, angle):
    angle = int(random.uniform(-angle, angle))
    h, w = img.shape[:2]
    M = cv2.getRotationMatrix2D((int(w/2), int(h/2)), angle, 1)
    img = cv2.warpAffine(img, M, (w, h))
    return img
In [6]:
def vertical_shift_down(img, ratio=0.0):
    if ratio > 1 or ratio < 0:
        print('Value should be less than 1 and greater than 0')
        return img
    ratio = random.uniform(-ratio, ratio)
    h, w = img.shape[:2]
    to_shift = h*ratio
    if ratio > 0:
        img = img[:int(h-to_shift), :, :]
    img = fill(img, h, w)
    return img
In [7]:
def vertical_shift_up(img, ratio=0.0):
    if ratio > 1 or ratio < 0:
        print('Value should be less than 1 and greater than 0')
        return img
    ratio = random.uniform(0.0, ratio)
    h, w = img.shape[:2]
    to_shift = h*ratio
    if ratio > 0:
        img = img[:int(h-to_shift), :, :]
    img = fill(img, h, w)
    return img
In [8]:
def horizontal_shift(img, ratio=0.0):
    if ratio > 1 or ratio < 0:
        print('Value should be less than 1 and greater than 0')
        return img
    ratio = random.uniform(-ratio, ratio)
    h, w = img.shape[:2]
    to_shift = w*ratio
    if ratio > 0:
        img = img[:, :int(w-to_shift), :]
    if ratio < 0:
        img = img[:, int(-1*to_shift):, :]
    img = fill(img, h, w)
    return img
In [9]:
def vertical_flip(img, flag):
    if flag:
        return cv2.flip(img, 0)
    else:
        return img
In [10]:
def horizontal_flip(img, flag):
    if flag:
        return cv2.flip(img, 1)
    else:
        return img
In [44]:
images = sorted(glob.glob('dataset/train/11/*.png'))
i = 0
In [45]:
print(len(images))
2500
In [46]:
dir = 'dataset/train/11/'
In [47]:
for fname in images:
    img = cv2.imread(fname)
    img = cv2.resize(img, dsize=(88, 88),interpolation=cv2.INTER_LINEAR)
    img = brightness(img, 30)
    img = contrast(img, 1, 1.5)
    img = horizontal_flip(img, 1)
    img = rotation(img, 180)
    img = horizontal_shift(img, 0.1)
    #if random.uniform(0,1) > 0.5:
    #    img = vertical_flip(img, 1)
    file_name = dir + str(i) + '.png'
    #file_name = 'aug_image/' + str(i) + '.png'
    cv2.imwrite(file_name, img)
    i = i + 1
    if i > 10000:
        break
In [48]:
for fname in images:
    img = cv2.imread(fname)
    img = cv2.resize(img, dsize=(88, 88),interpolation=cv2.INTER_LINEAR)
    img = brightness(img, 10)
    img = contrast(img, 1, 1.2)
    img = horizontal_flip(img, 1)
    img = rotation(img, 180)
    img = horizontal_shift(img, 0.2)
    #if random.uniform(0,1) > 0.5:
    img = vertical_flip(img, 1)
    file_name = dir + str(i) + '.png'
    #file_name = 'aug_image/' + str(i) + '.png'
    cv2.imwrite(file_name, img)
    i = i + 1
    if i > 10000:
        break
In [49]:
for fname in images:
    img = cv2.imread(fname)
    img = cv2.resize(img, dsize=(88, 88),interpolation=cv2.INTER_LINEAR)
    img = brightness(img, 20)
    img = contrast(img, 1, 1.3)
    img = horizontal_flip(img, 1)
    img = rotation(img, 90)
    img = horizontal_shift(img, 0.3)
    #if random.uniform(0,1) > 0.5:
    img = vertical_flip(img, 1)
    file_name = dir + str(i) + '.png'
    #file_name = 'aug_image/' + str(i) + '.png'
    cv2.imwrite(file_name, img)
    i = i + 1
    if i > 10000:
        break
In [146]:
for fname in images:
    img = cv2.imread(fname)
    img = cv2.resize(img, dsize=(88, 88),interpolation=cv2.INTER_LINEAR)
    img = brightness(img, 20)
    img = contrast(img, 1, 1.5)
    img = horizontal_flip(img, 1)
    img = rotation(img, 180)
    img = horizontal_shift(img, 0.1)
    #if random.uniform(0,1) > 0.5:
    #    img = vertical_flip(img, 1)
    file_name = dir + str(i) + '.png'
    #file_name = 'aug_image/' + str(i) + '.png'
    cv2.imwrite(file_name, img)
    i = i + 1
    if i > 9500:
        break
In [147]:
for fname in images:
    img = cv2.imread(fname)
    img = cv2.resize(img, dsize=(88, 88),interpolation=cv2.INTER_LINEAR)
    img = brightness(img, 10)
    img = contrast(img, 1, 1.5)
    img = horizontal_flip(img, 1)
    img = rotation(img, 180)
    img = horizontal_shift(img, 0.1)
    #if random.uniform(0,1) > 0.5:
    #    img = vertical_flip(img, 1)
    file_name = dir + str(i) + '.png'
    #file_name = 'aug_image/' + str(i) + '.png'
    cv2.imwrite(file_name, img)
    i = i + 1
    if i > 9500:
        break
In [148]:
for fname in images:
    img = cv2.imread(fname)
    img = cv2.resize(img, dsize=(88, 88),interpolation=cv2.INTER_LINEAR)
    img = brightness(img, 30)
    img = contrast(img, 1, 1.4)
    img = horizontal_flip(img, 1)
    img = rotation(img, 180)
    img = horizontal_shift(img, 0.3)
    #if random.uniform(0,1) > 0.5:
    img = vertical_flip(img, 1)
    file_name = dir + str(i) + '.png'
    #file_name = 'aug_image/' + str(i) + '.png'
    cv2.imwrite(file_name, img)
    i = i + 1
    if i > 9500:
        break

'Programming > OpenCV' 카테고리의 다른 글

Pyqt5와 OpenCV 연동시 주의점  (0) 2021.05.24