์ฌ์ง ์กฐ์ ํ๊ธฐ
์ฉ์ด์ ๋ฆฌ
- ์์ ํผ์ฌ๊ณ ์ฌ๋(shallow depth of field : DOF) :์
ธ๋ก์ฐ ํฌ์ปค์ค(shallow focus)
- ๋ฐฐ๊ฒฝ์ ํ๋ฆฌ๊ฒ ํ๋ ๊ธฐ์
๋ฐ์ดํฐ ์ค๋นํ๊ธฐ
- ๋ฐฐ๊ฒฝ์ด ์๋ ์
์นด๋ฅผ ์ดฌ์ํฉ๋๋ค. (๋ฐฐ๊ฒฝ๊ณผ ์ฌ๋์ ๊ฑฐ๋ฆฌ๊ฐ ์ฝ๊ฐ ๋ฉ๋ฆฌ ์์ผ๋ฉด ์ข์ต๋๋ค.)
- ์๋งจํฑ ์ธ๊ทธ๋ฉํ
์ด์
(Semantic segmentation)์ผ๋ก ํผ์ฌ์ฒด(์ฌ๋)์ ๋ฐฐ๊ฒฝ์ ๋ถ๋ฆฌํฉ๋๋ค.
- ๋ธ๋ฌ๋ง(blurring) ๊ธฐ์ ๋ก ๋ฐฐ๊ฒฝ์ ํ๋ฆฌ๊ฒ ํฉ๋๋ค.
- ํผ์ฌ์ฒด๋ฅผ ๋ฐฐ๊ฒฝ์ ์๋ ์์น์ ํฉ์ฑํฉ๋๋ค.
์ด๋ฏธ์ง์์ ๋ฐฐ๊ฒฝ๊ณผ ์ฌ๋ ๋ถ๋ฆฌํ๊ธฐ
import os
import urllib
import cv2
import numpy as np
from pixellib.semantic import semantic_segmentation
from matplotlib import pyplot as plt
print('์=3')
- urllib๋ ์น์์ ๋ฐ์ดํฐ๋ฅผ ๋ค์ด๋ก๋ํ ๋ ์ฌ์ฉํฉ๋๋ค.
- cv2๋ OpenCV ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ์ด๋ฏธ์ง๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด ํ์ํฉ๋๋ค.
- pixellib๋ ์๋งจํฑ ์ธ๊ทธ๋ฉํ
์ด์
์ ํธํ๊ฒ ์ฌ์ฉํ ์ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
img_path = '.human_segmentation/images/my_image.png'
img_orig = cv2.imread(img_path)
print(img_orig.shape)
plt.imshow(cv2.cvtColor(img_orig, cv2.COLOR_BGR2RGB))
plt.show()
Image Segmentation (์ด๋ฏธ์ง ์ธ๊ทธ๋ฉํ
์ด์
)
- ์ด๋ฏธ์ง์์ ํฝ์
๋จ์๋ก ๊ด์ฌ ๊ฐ์ฒด๋ฅผ ์ถ์ถํ๋ ๋ฐฉ๋ฒ
์๋งจํฑ ์ธ๊ทธ๋ฉํ
์ด์
(semantic segmentation)
- ๋ฌผ๋ฆฌ์ ์๋ฏธ ๋จ์๋ก ์ธ์ํ๋ ์ธ๊ทธ๋ฉํ
์ด์
- ์ด๋ฏธ์ง์์ ํฝ์
์ ์ฌ๋, ์๋์ฐจ, ๋นํ๊ธฐ ๋ฑ์ ๋ฌผ๋ฆฌ์ ๋จ์๋ก ๋ถ๋ฅ(classification)ํ๋ ๋ฐฉ๋ฒ
- ์๋งจํฑ ์ธ๊ทธ๋ฉํ
์ด์
์ '์ฌ๋'์ด๋ผ๋ ์ถ์์ ์ธ ์ ๋ณด๋ฅผ ์ด๋ฏธ์ง์์ ์ถ์ถํด ๋ด๋ ๋ฐฉ๋ฒ
์ธ์คํด์ค ์ธ๊ทธ๋ฉํ
์ด์
(Instance segmentation)
- ์ธ์คํด์ค ์ธ๊ทธ๋ฉํ
์ด์
์ ์ฌ๋ ๊ฐ๊ฐ์ธ๋ณ๋ก ๋ค๋ฅธ ๋ผ๋ฒจ์ ๊ฐ์ง๊ฒ
- ์ฌ๋ฌ ์ฌ๋์ด ํ ์ด๋ฏธ์ง์ ๋ฑ์ฅํ ๋ ๊ฐ ๊ฐ์ฒด๋ฅผ ๋ถํ ํด์ ์ธ์ํ์๋ ๊ฒ์ด ๋ชฉํ
CF ๋ฅ๋ฌ๋์ด์ ์ ์ด๋ฏธ์ง ์ธ๊ทธ๋ฉํ
์ด์
๋ฐฉ๋ฒ
- ์ํฐ์๋ ์ธ๊ทธ๋ฉํ
์ด์
(watershed segmentation)
- ์ด๋ฏธ์ง์์ ์์ญ์ ๋ถํ ํ๋ ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ ๋ฌผ์ฒด์ '๊ฒฝ๊ณ'๋ฅผ ๋๋๋ ๊ฒ
- ์ด๋ฏธ์ง๋ ๊ทธ๋ ์ด์ค์ผ์ผ(grayscale)๋ก ๋ณํํ๋ฉด 0~255์ ๊ฐ
- ํฝ์
๊ฐ์ ์ด์ฉํด์ ๊ฐ ์์น์ ๋๊ณ ๋ฎ์์ ๊ตฌ๋ถ
- ๋ฎ์ ๋ถ๋ถ๋ถํฐ ์์ํ '๋ฌผ'์ ์ฑ์ ๋๊ฐ๋ค๊ณ ์๊ฐํ๋ฉด ๊ฐ ์์ญ์์ ์ ์ ๋ฌผ์ด ์ฐจ์ค๋ฅด๋ค๊ฐ ๋์น๋ ์์
- ๊ทธ ๋ถ๋ถ์ ๊ฒฝ๊ณ์ ์ผ๋ก ๋ง๋ค๋ฉด ๋ฌผ์ฒด๋ฅผ ์๋ก ๊ตฌ๋ถ
opencv-python tutorial
DeepLab ์ธ๊ทธ๋ฉํ
์ด์
๋ชจ๋ธ
DeepLab V3+: Encoder-Decoder with Atrous Separable Convolution for Semantic Image Segmentation
- DeepLab์์ atrous convolution์ ์ฌ์ฉํ ์ด์
- receptive field๋ฅผ ๋๊ฒ ์ฌ์ฉํ๊ธฐ ์ํด ์ฌ์ฉ
- ์ ์ ํ๋ผ๋ฏธํฐ๋ก ํํฐ๊ฐ ๋ ๋์ ์์ญ์ ๋ณด๊ฒ ํ๊ธฐ ์ํด
- Depthwise separable convolution
- 3x3 conv layer ์ receptive field๋ฅผ 1/9 ์์ค์ ํ๋ผ๋ฏธํฐ๋ก ๊ตฌํํ ์ ์๊ธฐ ๋๋ฌธ์ ํจ์จ์
DeepLab ๋ชจ๋ธ์ ์ค๋น
- PixelLib๋ฅผ ์ด์ฉํ๋ฉด ํธํ๊ฒ ์ฌ์ฉ
PixelLib์์ ์ ๊ณตํด ์ฃผ๋ ๋ชจ๋ธ์ ๋ค์ด๋ก๋
model_dir = os.getenv('HOME')+'/aiffel/human_segmentation/models'
model_file = os.path.join(model_dir, 'deeplabv3_xception_tf_dim_ordering_tf_kernels.h5')
model_url = 'https://github.com/ayoolaolafenwa/PixelLib/releases/download/1.1/deeplabv3_xception_tf_dim_ordering_tf_kernels.h5'
urllib.request.urlretrieve(model_url, model_file)
๋ค์ด๋ก๋ํ ๋ชจ๋ธ์ ์ด์ฉํด PixelLib๋ก ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ ์ธ๊ทธ๋ฉํ
์ด์
๋ชจ๋ธ์ ์์ฑ
model = semantic_segmentation()
model.load_pascalvoc_model(model_file)
๋ชจ๋ธ์ ์ด๋ฏธ์ง๋ฅผ ์
๋ ฅ
segvalues, output = model.segmentAsPascalvoc(img_path)
- segmentAsPascalvoc๋ผ๋ ํจ์
- PASCAL VOC ๋ฐ์ดํฐ๋ก ํ์ต๋ ๋ชจ๋ธ์ ์ด์ฉํ๋ค๋ ์๋ฏธ
- PASCAL VOC ๋ฐ์ดํฐ์ ๋ผ๋ฒจ ์ข
๋ฅ
LABEL_NAMES = [
'background', 'aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus',
'car', 'cat', 'chair', 'cow', 'diningtable', 'dog', 'horse', 'motorbike',
'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tv'
]
len(LABEL_NAMES)
21
background๋ฅผ ์ ์ธํ๋ฉด 20๊ฐ์ ํด๋์ค
20 ์ ์๋ฏธ๋ tv
๋ชจ๋ธ์์ ๋์จ ์ถ๋ ฅ๊ฐ ํ์ธ
plt.imshow(output)
plt.show()
segvalues
{'class_ids': array([ 0, 9, 15]),
'masks': array([[False, False, False, ..., False, False, False],
[False, False, False, ..., False, False, False],
[False, False, False, ..., False, False, False],
...,
[False, False, False, ..., False, False, False],
[False, False, False, ..., False, False, False],
[False, False, False, ..., False, False, False]])}
for class_id in segvalues['class_ids']:
print(LABEL_NAMES[class_id])
background
chair
person
- output์๋ ์ธ๊ทธ๋ฉํ
์ด์
์ด ๋ ๊ฒฐ๊ณผ๊ฐ ๊ฐ๊ฐ ๋ค๋ฅธ ์์์ผ๋ก ๋ด๊ฒจ ์์
- segvalues์๋ class_ids์ masks๊ฐ ์์
- class_ids๋ฅผ ํตํด ์ด๋ค ๋ฌผ์ฒด๊ฐ ๋ด๊ฒจ ์๋์ง ํ์ธ ๊ฐ๋ฅ
๋ฌผ์ฒด๋ง๋ค output์ ์ด๋ค ์์์ผ๋ก ๋ํ๋ ์๋์ง ํ์ธ
colormap = np.zeros((256, 3), dtype = int)
ind = np.arange(256, dtype=int)
for shift in reversed(range(8)):
for channel in range(3):
colormap[:, channel] |= ((ind >> channel) & 1) << shift
ind >>= 3
colormap[:20]
array([[ 0, 0, 0],
[128, 0, 0],
[ 0, 128, 0],
[128, 128, 0],
[ 0, 0, 128],
[128, 0, 128],
[ 0, 128, 128],
[128, 128, 128],
[ 64, 0, 0],
[192, 0, 0],
[ 64, 128, 0],
[192, 128, 0],
[ 64, 0, 128],
[192, 0, 128],
[ 64, 128, 128],
[192, 128, 128],
[ 0, 64, 0],
[128, 64, 0],
[ 0, 192, 0],
[128, 192, 0]])
PixelLib์ ๋ฐ๋ฅด๋ฉด ์์ ๊ฐ์ ์์ ์ฌ์ฉ
์ฌ๋์ ๋ํ๋ด๋ 15๋ฒ์งธ ์์์
colormap[15]
array([192, 128, 128])
๋ฌผ์ฒด๋ฅผ ์ฐพ์๋ด๊ณ ์ถ๋ค๋ฉด colormap[class_id] ์ฌ์ฉ
- output ์ด๋ฏธ์ง๊ฐ BGR ์์๋ก ์ฑ๋ ๋ฐฐ์น๊ฐ ๋์ด ์๋ค
- colormap์ RGB ์์
์ถ์ถํด์ผ ํ๋ ์์ ๊ฐ์ ์์๋ฅผ ์๋์ฒ๋ผ ๋ฐ๊ฟ ์ค์ผ
seg_color = (128,128,192)
seg_color๋ก๋ง ์ด๋ฃจ์ด์ง ๋ง์คํฌ๋ฅผ ๋ง๋ค๊ธฐ
seg_map = np.all(output==seg_color, axis=-1)
print(seg_map.shape)
plt.imshow(seg_map, cmap='gray')
plt.show()
(731, 579)
- 3์ฑ๋ ๊ฐ์ก๋ ์๋ณธ๊ณผ๋ ๋ค๋ฅด๊ฒ ์ฑ๋ ์ ๋ณด๊ฐ ์ฌ๋ผ์ง
๊ฒน์ณ์ ๋ณด๊ธฐ(์ธ๊ทธ๋ฉํ
์ด์
์ด ์๋์๋์ง ํ์ธ)
addWeighted
applyColorMap
img_show = img_orig.copy()
img_mask = seg_map.astype(np.uint8) * 255
color_mask = cv2.applyColorMap(img_mask, cv2.COLORMAP_JET)
img_show = cv2.addWeighted(img_show, 0.6, color_mask, 0.4, 0.0)
plt.imshow(cv2.cvtColor(img_show, cv2.COLOR_BGR2RGB))
plt.show()
์ ํ์ธ์ด ์๋์ OCEAN์ผ๋ก ๋ณ๊ฒฝ
cf Colormap Types ๋ณ๊ฒฝ
๋ฐฐ๊ฒฝ ํ๋ฆฌ๊ฒ
blur() ํจ์๋ฅผ ์ด์ฉ
img_orig_blur = cv2.blur(img_orig, (13,13))
plt.imshow(cv2.cvtColor(img_orig_blur, cv2.COLOR_BGR2RGB))
plt.show()
- ํ๋ ค์ง ์ด๋ฏธ์ง์์ ๋ฐฐ๊ฒฝ๋ง ์ถ์ถ
img_mask_color = cv2.cvtColor(img_mask, cv2.COLOR_GRAY2BGR)
img_bg_mask = cv2.bitwise_not(img_mask_color)
img_bg_blur = cv2.bitwise_and(img_orig_blur, img_bg_mask)
plt.imshow(cv2.cvtColor(img_bg_blur, cv2.COLOR_BGR2RGB))
plt.show()
bitwise_not ํจ์๋ฅผ ์ด์ฉํ๋ฉด ์ด๋ฏธ์ง๊ฐ ๋ฐ์
- ์๋ ๋ง์คํฌ์์๋ ๋ฐฐ๊ฒฝ์ด 0, ์ฌ๋์ด 255
- bitwise_not ์ฐ์ฐ์ ํ๊ณ ๋๋ฉด ๋ฐฐ๊ฒฝ์ 255, ์ฌ๋์ 0
cf
๋ฐ์ ๋ ์ธ๊ทธ๋ฉํ
์ด์
๊ฒฐ๊ณผ๋ฅผ ์ด์ฉํด์ ์ด๋ฏธ์ง์ bitwise_and ์ฐ์ฐ์ ์ํํ๋ฉด ๋ฐฐ๊ฒฝ๋ง ์๋ ์์์ ์ป์ ์ ์์ต๋๋ค. 0๊ณผ ์ด๋ค ์๋ฅผ bitwise_and ์ฐ์ฐ์ ํด๋ 0์ด ๋๊ธฐ ๋๋ฌธ์ ์ฌ๋์ด 0์ธ ๊ฒฝ์ฐ์๋ ์ฌ๋์ด ์๋ ๋ชจ๋ ํฝ์
์ด 0์ด ๋ฉ๋๋ค. ๊ฒฐ๊ตญ ์ฌ๋์ด ์ฌ๋ผ์ง๊ฒ ๋๋ ๊ฑฐ์ฃ .
ํ๋ฆฐ ๋ฐฐ๊ฒฝ๊ณผ ์๋ณธ ์์ ํฉ์ฑ
img_concat = np.where(img_mask_color==255, img_orig, img_bg_blur)
plt.imshow(cv2.cvtColor(img_concat, cv2.COLOR_BGR2RGB))
plt.show()
์ธ๊ทธ๋ฉํ
์ด์
๋ง์คํฌ๊ฐ 255์ธ ๋ถ๋ถ๋ง ์๋ณธ ์ด๋ฏธ์ง ๊ฐ์ ๊ฐ์ง๊ณ ์ค๊ณ ์๋ ์์ญ์ ๋ธ๋ฌ๋ ์ด๋ฏธ์ง ๊ฐ์ ์ฌ์ฉ
np.where(์กฐ๊ฑด, ์ฐธ์ผ๋, ๊ฑฐ์ง์ผ๋)์ ํ์์ ์ฝ๋๋ฅผ ์ฌ์ฉ
numpy.where
๋น๊ต
์๋ณธ | ๋ณํ |
---|
| |
- ์ธ๋ฌผ๊ณผ ๋ฐฐ๊ฒฝ์ ๊ฑฐ๋ฆฌ ์ฐจ์ด๊ฐ ์๊ณ ๊ฑฐ๋ฆฌ๊ฐ ์ผ์ ํ ์๋ก ๋ ์์ฐ์ค๋ฌ์ ๋ณด์
๋ฌธ์ ์ ์ฐพ๊ธฐ
STEP 1.
- ์ฌ๋ฌ๋ถ์ ์
์นด๋ฅผ ์ด์ฉํด์ ์ค๋ ๋ฐฐ์ด ๋ด์ฉ์ ์ํํด ๋ด
์๋ค. ์๋์ ๊ฐ์ ์ด๋ฏธ์ง๋ฅผ ์ป์ด์ผ ํฉ๋๋ค. ์ต์ 3์ฅ ์ด์์ ์ธ๋ฌผ๋ชจ๋ ์ฌ์ง์ ๋ง๋ค์ด ๋ด
์๋ค.
- ์ธ๋ฌผ์ด ์ฃผ์ธ๊ณต์ด ์๋, ๊ท์ฌ์ด ๊ณ ์์ด์ ๋ํ ์์ํฌ์ปค์ฑ ์ฌ์ง๋ ๋ง๋ค์ด ๋ณผ ์ ์์ ๊ฒ์
๋๋ค. ์๋งจํฑ ์ธ๊ทธ๋ฉํ
์ด์
์คํ
์์ ํํธ๋ฅผ ์ฐพ์๋ด
์๋ค.
- ๋ฐฐ๊ฒฝ์ blurํ๋ ์ธ๋ฌผ๋ชจ๋ ์ฌ์ง์ด ์๋๋ผ ๋ฐฐ๊ฒฝ์ฌ์ง์ ๋ค๋ฅธ ์ด๋ฏธ์ง๋ก ๊ต์ฒดํ๋ ํฌ๋ก๋งํค ๋ฐฐ๊ฒฝ ํฉ์ฑ์ ์๋ํด ๋ณผ ์๋ ์์ ๊ฒ์
๋๋ค. ์ฌ๋ฌ๋ถ๋ง์ ํ์์ ์ธ ์ฌ์ง์ ๋ง๋ค์ด ๋ณด๋ฉด ์ด๋จ๊น์?
STEP 2.
- ์ธ๋ฌผ ์์ญ์ ํฌํจ๋์ด blur๋์ง ์๊ณ ๋์จ๋ค
- ์ธ๋ฌผ ๋ชจ๋ ์ฌ์ง ์ค ํ๋์์๋ ์ด์ํ ์์น๋ฅผ ์ฐพ์ ํ์
STEP 3. ์๋ฃจ์
์ ์
- ์ ํํ ๊ธฐ์ ์ด DeepLab ๋ชจ๋ธ์ Semantic Segmentation ์ด ๋ง๋ค์ด ๋ธ Mask ์์ญ์ ์ด๋ป๊ฒ ์ ์ฉ๋์ด ๋ฌธ์ ์ ์ ๋ณด์ํ๊ฒ ๋๋์ง์ ๋ฉ์ปค๋์ฆ์ด ํฌํจ๋ ์๋ฃจ์
์ธ๊ทธ๋ฉํ
์ด์
์ ํ๊ณ
- Semantic segmentation์ ๋ถ์ ํ์ฑ์ด ์ฌ๋ฌ ๊ฐ์ง ๋ฌธ์ ๋ฅผ ๋ฐ์์ํค๋ ์ฃผ์ ์์ธ
- ํผ์ฌ๊ณ์ฌ๋๋ฅผ ์ด์ฉํ ๋ณด์ผ(์์ํฌ์ปค์ฑ) ํจ๊ณผ๋ ๋ง ๊ทธ๋๋ก ์ฌ๋๋ฅผ ํํํ๊ธฐ ๋๋ฌธ์ ์ด์ ์ด ์กํ ๊ฑฐ๋ฆฌ๋ฅผ ๊ดํ์ ์ผ๋ก ์์ฃผ ์ฌ์ธํ๊ฒ ๊ตฌ๋ณ(segmentation)
- ์ด๋ฅผ ๋ชจ๋ฐฉํ semantic segmentation ๋ชจ๋์ ์ ํ๋๊ฐ 1.00 ์ด ๋์ง ์๋ ํ ์๋ฒฝํ ๊ตฌํํ๊ธฐ ์ด๋ ค์
ํผ์ฌ๊ณ ์ฌ๋ ์ดํด.
3D Camera ํ์ฉ
์ํํธ์จ์ด ๊ธฐ์ ํ์ฉํ๊ธฐ
๋ค๋ฅธ ๊ธฐ์ ๊ณผ ์ตํฉ
Reference
Segmetation ์ฐธ๊ณ ์๋ฃ