Azure Zest

[ python ] 사진 원하는 모양으로 오려내기 본문

Deep Learning

[ python ] 사진 원하는 모양으로 오려내기

LABONG_R 2020. 2. 8. 00:46

사진을 원하는 모양을 잡아 그 부분만 segmentation 해보자.

사진을 이진화시킨 후, 경계면을 다듬어 마스크를 만들어 낸 후, 이를 사진에 다시 적용시켜 그 부위를 오려내고자 한다.

 

0. 사용할 라이브러리 import

import cv2
import numpy as np
import matplotlib.pyplot as plt
from skimage.segmentation import clear_border
import skimage.morphology as mp
import scipy.ndimage.morphology as sm

 

1. 사진 이진화 하기

다음과 같은 사과 사진이 있다고 하자. 

마스크를 만들기 위해 이진화를 시킬텐데, opencv를 이용할 것이다. 이 때, binary를 적용시키기 위해 흑백으로 영상을 불러낸다.

img = cv2.imread('/content/drive/My Drive/lung/다운로드.jpg',0)
print(img.shape)     #  --> (183,276)

위와 같이 cv2.imread 뒤에 0을 붙이면 흑백으로 불러들이게 된다. 

그 다음, 임계값을 잡아 다음과 같이 이진화시킨다. (Reference 1 참고)

th,img1 = cv2.threshold(img,0,255,cv2.THRESH_OTSU)

 

2. 그림 다듬기

2-1. 형태 잡기

여러가지 방법을 이용하여 추출하고 싶은 마스크의 대략적인 모양을 만든다. (흰 부분이 마스크에 해당하므로 원하는 부분이 흰 색(1)이 되도록 고치자.) (Reference 2 참고)

img1 = 255-img1   # 위의 사과 그림은 까만색(0)이므로 반전해준다.
img2 = clear_border(img1)  # 경계면을 다듬는다.

disk2 = mp.disk(2) # 디스크 생성
# 여러가지 morphology mothod를 이용
img2 = mp.binary_dilation(img2, disk2)
img2 = mp.binary_erosion(img2, disk2)
img2 = mp.binary_opening(img2, disk2)
img2 = mp.binary_closing(img2, disk2)

 

2-2. 구멍 메우기

위의 사과 마스크 안의 구멍을 메워준다.

img2 = sm.binary_fill_holes(img2)

 

3. 마스크와 사진 겹치기

위의 생성된 마스크와 사진을 겹쳐 마스크에 해당하는 부분을 사진에서 얻는다.

img2 = (img2*1).astype('uint8') # cv2의 기본 데이터타입은 'uint8'이므로 바꿔준다.
masked = cv2.bitwise_or(img,img,mask=img2) 

 

4. 사진 보기

plt.imshow(img)
plt.imshow(img, cmap='gray') # 흑백으로 사진을 보고싶을 때

 

사진을 원하는 모양으로 오려내는 방법을 살펴보았다.

본문에서는 간단하게 살표보았지만, 마스크의 모양을 좀 더 세세하게 다듬으면 원하는 모양을 얻을 수 있을 것이다.

 

Reference

1. opencv - 이미지 임계처리

 

이미지 임계처리 — gramman 0.1 documentation

기본 임계처리 이진화 처리는 간단하지만, 쉽지 않은 문제를 가지고 있다. 이진화란 영상을 흑/백으로 분류하여 처리하는 것을 말합니다. 이때 기준이 되는 임계값을 어떻게 결정할 것인지가 중요한 문제가 됩니다. 임계값보다 크면 백, 작으면 흑이 됩니다. 기본 임계처리는 사용자가 고정된 임계값을 결정하고 그 결과를 보여주는 단순한 형태입니다. 이때 사용하는 함수가 cv2.threshold() 입니다. cv2.threshold(src, thresh, maxval

opencv-python.readthedocs.io

2. Morphology

 

Module: morphology — skimage v0.17.dev0 docs

If True, a pixel at coordinate, e.g., (4, 7) will be represented by coordinates (3.5, 7), (4.5, 7), (4, 6.5), and (4, 7.5). This adds some “extent” to a pixel when computing the hull.

scikit-image.org

3. opencv operation

 

Operations on Arrays — OpenCV 2.4.13.7 documentation

Parameters: mat – 2D or N-dimensional matrix; currently matrices with more than 4 channels are not supported by the methods, use Mat::reshape() as a possible workaround. distType – distribution type, RNG::UNIFORM or RNG::NORMAL. a – first distribution para

docs.opencv.org