머신러닝과 딥러닝/딥러닝

Image Cropping(이미지 자르기) by Python, Numpy

Stat_in_KNU 2020. 12. 2. 22:26

Python의 Numpy를 활용하여 Image를 Cropping해보겠습니다.

프로젝트 보안상 예시 이미지만을 활용하는 점 이해해주세요

 

목적은 흑/백으로만 이루어진 데이터에서 Object주위에 Margin을 어느정도 주고, 잘라내는 것 입니다.

 

예를 들어

 

출처 : https://www.ui4u.go.kr/depart/contents.do?mId=0413000000

이미지에서 코 부분만 따로 떼어내는 작업(Cropping)이라고 할 수 있습니다.

분류모델을 만들기 전의 전처리 작업이라고 보시면 될 것 같네요.

 


 

Package import

import os
import numpy as np
import cv2
from matplotlib import pyplot as plt

 

Image Read

path = 'ch/001/001_Test/'
img = cv2.imread(root + 'a_372874_m_R_1.jpg')

 

Plotting Image

plt.imshow(img, cmap = 'gray')

Cleansing Image

JPG타입 이미지는 노이즈를 가지고 있습니다.(있을 수도 있습니다.)

실제로 np.unique로 확인해보면 noise가 섞여있습니다.

np.unique(img)

 

다음과 같이 대충 0과 255로 이진화 해주겠습니다.

img[img < 125] = 0
img[img >=125] = 255 

다시 unique로 확인

np.unique(img)

깔끔해졌네요!

 

img의 차원을 확인해볼게요

img.shape

모델은 Gray Channel로 만들어 줄거기 때문에 RGB채널을 GRAY채널로 바꿔줄겁니다.

 

gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

 

이제 전처리 작업이 끝났습니다!

 


본격적으로 Image Cropping에 들어가보겠습니다.

 

Not Cropped Image

Cropping은 하얀색 영역(255 pixel) 을 주위로 30의 마진을 가지는 직사각형 형태로 잘라줄거에요.

데이터는 Numpy Array이기 때문에 어렵지 않게 할 수 있습니다.

 

다음과 같은 과정을 거치면 됩니다.

1. masking - 현재 0과 255를 가지는 Numpy Array(Image Data)를 0이면 False, 255이면 True를 가지는 Array로 바꾸어줍니다.

2. numpy array의 attribute인 any를 이용해서 각 행, 열을 기준으로 True를 가지고 있는지 여부를 확인하는 array를 만들어줍니다.

3. argmax를 이용하여 각 행, 열에 대해 조건을 만족하는 최대, 최소 Index를 구해줍니다.

4. 이미지를 리턴하는데, 파이썬은 음수인덱스에대해 최대인덱스로 가는 성질이 있어 max 함수를 이용합니다.

 

def crop(img, tol = 0):
    mask = img > tol
    m, n = mask.shape
    mask0, mask1 = mask.any(axis = 0), mask.any(axis = 1)
    col_start, col_end = mask0.argmax(), n-mask0[::-1].argmax()
    row_start, row_end = mask1.argmax(), m-mask1[::-1].argmax()
    return img[max(0,row_start-30):row_end+30, max(0, col_start-30):col_end+30]
plt.imshow(crop(img), cmap = 'gray')

cropped image

끝.