๐Ÿ“‘ํ”„๋กœ์ ํŠธ-์–ผ๊ตด์ธ์‹

์œ ๋ น๊ฐœยท2021๋…„ 11์›” 19์ผ
0

ํ”„๋กœ์ ํŠธ

๋ชฉ๋ก ๋ณด๊ธฐ
3/5

์–ผ๊ตด์ธ์‹ ํ”„๋กœ์ ํŠธ!

์•„๋งˆ ๋‚ด ์ธ์ƒ ์ฒซ ํ”„๋กœ์ ํŠธ ์˜€๋˜ ๊ฒƒ ๊ฐ™๋‹ค.
4๋ช…์ด์„œ ๊ฐ™์ด ํ–ˆ๋Š”๋ฐ git bash๊ฐ€ ๊ณ„์† ์˜ค๋ฅ˜๋‚˜์„œ ๋๊นŒ์ง€ ๊นƒํ—ˆ๋ธŒ์— ๋ชป ์˜ฌ๋ ธ๋˜๊ฒŒ ๊ธฐ์–ต์— ๋‚จ๋Š”๋‹ค ใ…‹ใ…‹...
์ตœ๋Œ€ํ•œ ๊ทธ ๋‹น์‹œ์˜ ๊ธฐ์–ต๊ณผ ์ฝ”๋“œ๋“ค์„ ๋˜์งš์–ด๋ณด๋ฉฐ ์ ์–ด๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค ใ…œใ…œ


๐Ÿ“”๋‹น์‹œ์— ๊ธฐ๋กํ–ˆ๋˜ ๋ณด๊ณ ์„œ ( ์ตœ์ข… ์ˆ˜์ •์ผ 2020.04.13 )

1.๊ฐœ์š”

ํŒ€์›๋“ค๋ผ๋ฆฌ ํ”„๋กœ์ ํŠธ ์ฃผ์ œ๋ฅผ ์ •ํ–ˆ๋‹ค. 4๋ช…๋‹ค ์–ผ๊ตด์ธ์‹์— ๊ด€๋ จํ•˜์—ฌ ๊ด€์‹ฌ์ด ์žˆ์—ˆ๊ธฐ์— ๊ณ ์‹ฌํ•˜์—ฌ ์ฃผ์ œ๋ฅผ ์ •ํ•˜๊ณ  ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๊ณผ์ •์„ ์ •ํ–ˆ๋‹ค. ์ฃผ์ œ๋Š” ์–ผ๊ตด์„ ์ œ์™ธํ•œ ํ™”๋ฉด์„ ๋ธ”๋Ÿฌ ์ฒ˜๋ฆฌํ›„ ๊ฐ์ •์— ๋”ฐ๋ผ ๋ฐฐ๊ฒฝ์„ ๋ฐ”๊ฟ”์ฃผ๋Š”, ์ผ์ข…์˜ ์ธ๊ณต์ง€๋Šฅ ์นด๋ฉ”๋ผ(?)๋กœ ์ง„ํ–‰๋  ๊บผ ๊ฐ™๋‹ค. ์ˆœ์„œ๋Š” ์–ผ๊ตด ํ‹€๋”ฐ๊ธฐ->๊ฐ์ •์ธ์‹-> ๊ฐ์ •์— ๋”ฐ๋ฅธ ๋ฐฐ๊ฒฝ ๋ฐ”๊ฟ”์ฃผ๊ธฐ๋กœ ์ง„ํ–‰ํ•˜๊ธฐ๋กœ ํ•˜์˜€์œผ๋ฉฐ, ํ”„๋กœ๊ทธ๋žจ์€ ๊ฐ€์žฅ ๋ณดํŽธํ™”๋˜์–ด์žˆ๊ณ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(๋ชจ๋“ˆ,ํŒจํ‚ค์ง€)๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์šฉ์ดํ•œ ํŒŒ์ด์ฌ ์„ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ํ•˜์˜€๋‹ค.

2.๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ ํƒ

ํŒŒ์ด์ฌ ํ”„๋กœ๊ทธ๋žจ์ค‘ ์–ด๋–ค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ด ํ”„๋กœ์ ํŠธ์— ๊ฐ€์žฅ ์–ด์šธ๋ฆด์ง€ ์ฐพ์•„๋ณด์•˜๋‹ค. ์˜์ƒ ์ฒ˜๋ฆฌ์™€ ๊ด€๋ จํ•ด์„œ numpy,ImajeJ,PIL(Python Imaging Library)๋“ฑ ๋งŽ์€ ์˜์ƒ์ฒ˜๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์กฐ์‚ฌํ•ด๋ณผ์ˆ˜ ์žˆ์—ˆ๋Š”๋ฐ, ๊ทธ์ค‘ ์••๋„์ ์œผ๋กœ ์˜์ƒ ์ฒ˜๋ฆฌ ๋ถ„์•ผ์— ์“ฐ์ด๋Š” ๋Œ€ํ‘œ์ ์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ์—ˆ๋‹ค. ๋ฐ”๋กœ Opencv. Opencv๋Š” ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค๊ณผ ํ•จ๊ป˜ ์“ฐ๋ฉฐ ์˜์ƒ์ฒ˜๋ฆฌ ๋ถ„์•ผ์— ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์“ฐ์ด๊ณ , ์‚ฌ์ง„์„ ์‰ฝ๊ฒŒ ๋‚˜๋ˆ  ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํŽธ๋ฆฌํ•˜๋ฉฐ ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“ค ํ”„๋กœ์ ํŠธ์ธ ์ธ๊ณต์ง€๋Šฅ ๊ฐ์ • ์ธ์‹ ์นด๋ฉ”๋ผ์— ์ ํ•ฉํ•˜๋‹ค๊ณ  ์ƒ๊ฐ๋˜์–ด ์šฐ์„  Opencv๋ฅผ ์—ฐ๊ตฌํ•ด๋ณด๊ธฐ๋กœ ํ•˜์˜€๋‹ค.

3.OpenCV ์—ฐ์Šต

์ผ๋‹จ python์— Opencv๋ฅผ ์„ค์น˜ํ•˜๋Š” ๊ณผ์ •๋ถ€ํ„ฐ ์—ฐ์Šตํ•ด๋ณด์•˜๋‹ค. ์ „์— ์ง„ํ–‰ํ•˜๋˜ ๊ฒŒ์ž„ ํ”„๋กœ์ ํŠธ์™€ ์—‰ํ‚ค์ง€ ์•Š๊ธฐ ์œ„ํ•ด ์•„๋‚˜์ฝ˜๋‹ค๋ฅผ ์„ค์น˜, ์•„๋‚˜์ฝ˜๋‹ค ํ”„๋กฌํ”„ํŠธ์— !pip install opencv-contrib-python์„ ์„ค์น˜ํ•˜๋ฉด ๋˜๋Š” ๊ฐ„๋‹จํ•œ ๊ณผ์ •์ด์—ˆ๋‹ค.
Opencv๋ฅผ ์—ฐ์Šตํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ€์žฅ ๊ธฐ์ดˆ ๊ณผ์ •์ธ ์‚ฌ์ง„์„ ์ถœ๋ ฅํ•ด๋ณด์•˜๋‹ค.

import cv2 
img_file = 'img/figures.jpg' # ์ด๋ฏธ์ง€ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
img = cv2.imread(img_file) # ์ด๋ฏธ์ง€ ๋ณ€์ˆ˜ ํ• ๋‹น
cv2.imshow('IMG', img) # ํ™”๋ฉด ํ‘œ์‹œ ์ฐฝ์ด๋ฆ„ : 'IMG' 
cv2.waitKey()
cv2.destroyAllWindows()

์œ„ ์ฝ”๋“œ๊ฐ€ Opencv ์‚ฌ์ง„์ถœ๋ ฅ์˜ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ด ๋˜๋Š” ์ฝ”๋“œ๋‹ค. img_file์ด๋ž€ ๋ณ€์ˆ˜์— ์ž์‹ ์ด ๋‹ด์•„์˜ฌ ์ด๋ฏธ์ง€๋ฅผ ์ €์žฅํ•ด์ฃผ๊ณ , img๋Š” ์ด ์ด๋ฏธ์ง€ํŒŒ์ผ์„ ์ฝ์–ด์ค€๋‹ค. ๊ทธ๋ฆฌ๊ณ ์„œ cv2.imshow๋ผ๋Š” ๋ช…๋ น์–ด๋ฅผ ์ด์šฉํ•ด ์‚ฌ์ง„์„ ๋ณด์—ฌ์ค€ ๋’ค destroyAllwindows๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฐฝ์„ ๋‹ซ์•„์ฃผ๋ฉด ๋œ๋‹ค.

๐Ÿ’ปํ”„๋กœ์ ํŠธ ์‹œ์ž‘

์–ผ๊ตด ํ‹€๋”ฐ๊ธฐ

ํ”„๋กœ์ ํŠธ์˜ ์ฒซ๋ฒˆ์งธ ๋‹จ๊ณ„์ธ ์–ผ๊ตด ํ‹€๋”ฐ๊ธฐ๋ฅผ ์‹œ์ž‘ํ•˜์˜€๋‹ค. OpenCv๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์‚ฌ๋ฌผ์„ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋งŽ์•˜๋Š”๋ฐ, ์ฒ˜์Œ์—” Contour๋ผ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ดํŽด๋ณด์•˜๋‹ค.

import cv2
img_color = cv2.imread('C:/Users/GhostDog/Desktop/test.png')
img_gray = cv2.cvtColor(img_color, cv2.COLOR_BGR2GRAY)
ret, img_binary = cv2.threshold(img_gray,127,255,0)contours, 
hierarchy = cv2.findContours(img_binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
print(contours)
cv2.drawContours(img_color, contours, 0,(0,0,255),3)
cv2.drawContours(img_color, contours, 1,(0,255,0),3)cv2.imshow("result",img_color)
cv2.waitKey(0)

์‹คํ–‰ ๊ฒฐ๊ณผ

Coutour๋ผ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋ช…์•” ๋ฐ๊ธฐ๋ฅผ ํŒ๋‹จํ•˜์—ฌ ๋ณด์—ฌ์ฃผ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค. ์œ„์— Drawcontours๋กœ ๋‘ ๊ทธ๋ฆผ์— (0,0,255)๋นจ๊ฐ„์ƒ‰ ํ…Œ๋‘๋ฆฌ์™€ (0,255,0)์ดˆ๋ก์ƒ‰ ํ…Œ๋‘๋ฆฌ๋กœ ์ฃผ๋ณ€ ๋ฐ๊ธฐ์™€ ๋‹ค๋ฅธ ๋ณ„๊ณผ ์‚ผ๊ฐํ˜•์œผ๋กœ ๊ตฌ๋ถ„์„ ํ•ด๋ณด์•˜๋‹ค. Contour๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฒˆ ๋‹จ๊ณ„์˜ ๋ชฉํ‘œ์ธ ์–ผ๊ตด ํ‹€๋”ฐ๊ธฐ(์–ผ๊ตด๊ณผ ์ „๊ฒฝ ๋ถ„๋ฆฌ)๋ฅผ ์‹œ๋„ํ•ด๋ณด์•˜๋‹ค.

๋ณด๋‹ค์‹œํ”ผ ์ผ๋ถ€๋Ÿฌ ๋ฐฐ๊ฒฝ์„ ๋ฐ๊ฒŒํ•˜๊ณ  ์˜ท๊ณผ ์–ผ๊ตด์„ ๋น„๊ต์  ์–ด๋‘์šด ์ƒ‰์œผ๋กœ ์ž…์–ด๋„ Contour๋กœ๋Š” ํ‹€ ๊ตฌ๋ถ„์ด ๋˜์ง€ ์•Š์•˜๋‹ค. ์ž๋ฃŒ ์กฐ์‚ฌ๋ฅผ ๋”ํ•ด๋ณด๋‹ˆ Contour๋Š” ๊ทน๋‹จ์ ์ธ ์ƒ‰์˜ ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ์ฃผ๋ณ€ ๋ฐฐ๊ฒฝ ์‚ฌ๋ฌผ์ด ๋„ˆ๋ฌด ๋ˆˆ์— ๋„๋ฉด ๊ตฌ๋ถ„์ด ์ž˜ ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“œ๋ ค๋Š” ํ”„๋กœ์ ํŠธ์— ์ ์šฉ์‹œํ‚ค๊ธฐ์—๋Š” ์–ด๋ ค์›€์ด ์žˆ์–ด ์ ์šฉ์‹œํ‚ค๊ธฐ ์–ด๋ ต๋‹ค๊ณ  ์ƒ๊ฐํ•˜์˜€๋‹ค.
์–ผ๊ตด๊ณผ ์ „๊ฒฝ ๋ถ„๋ฆฌ์— ํฌ์ปค์Šค๋ฅผ ๋งž์ถฐ ํŒŒ์ด์ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋” ์ฐพ์•„๋ณด์•˜๋‹ค
.
์œ„ ์‚ฌ์ง„์€ ์–ผ๊ตด๊ณผ ์ „๊ฒฝ ๋ถ„๋ฆฌ์— ์“ฐ์ด๋Š” ๋Œ€ํ‘œ์ ์ธ ํˆด๋“ค์ด๋‹ค. ๋‹น์‹œ์— ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๊ด€๋ จํ•˜์—ฌ ํŠน์ง•๊ณผ ์žฅ๋‹จ์ ์„ ์ •๋ฆฌํ•œ ๊ธ€์ด ์žˆ๊ธฐ์— ์ ์–ด๋ดค๋‹ค.


Magic Wand ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • ์œ„์น˜๋‚˜ ์˜์—ญ์„ ์ง€์ •ํ•˜๋ฉด, ๊ทธ์™€ ์—ฐ๊ฒฐ๋œ ํ”ฝ์…€๋“ค ์ค‘ ๊ทธ ์ฐจ์ด๊ฐ€ ํŠน์ • ๊ฐ’ ์ด๋‚ด์ธ ํ”ฝ์…€๋“ค์„ ์„ ํƒํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. Background์™€ Foreground์˜ ํ”ฝ์…€ ๊ฐ’ ๋ถ„ํฌ๊ฐ€ ์„œ๋กœ ๊ฒน์น˜๋ฉด ๊ณค๋ž€ํ•ด์ง‘๋‹ˆ๋‹ค.

Intelligent Scissors Mortensen, Barret์˜ ์ œ์•ˆํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ๋งˆ์šฐ์Šค๋ฅผ ์›€์ง์—ฌ๊ฐ€๋ฉฐ ๋Œ€๊ฐ•์˜ ํฌ์ธํŠธ๋ฅผ seed๋กœ ์ง€์ •ํ•˜์—ฌ ์˜์—ญ์„ ์„ ํƒํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์‹ค์‹œ๊ฐ„์œผ๋กœ ํ˜„์žฌ ์ปค์„œ์˜ ์œ„์น˜์™€ ์ง์ „ seed ์œ„์น˜ ์‚ฌ์ด์˜ minimum cost path๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ํ˜„์žฌ ํ‘œ์‹œ๋˜๋Š” ๊ฒฝ๋กœ๊ฐ€ ๋งˆ์Œ์— ๋“ค๋ฉด ๊ฒฝ๋กœ๋ฅผ ๊ณ ์ •ํ•˜๊ณ  ํ˜„์žฌ ์œ„์น˜๋ฅผ ๋‹ค์Œ seed๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ๋ฐ˜๋ณตํ•˜์—ฌ ์˜์—ญ์„ ์„ ํƒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด ๋ฐ”์—…์˜ ๊ฒฝ์šฐ ํ…์Šค์ณ๊ฐ€ ๋ณต์žกํ•œ ์˜์—ญ์ด๊ฑฐ๋‚˜ ์•„์˜ˆ ํ…์Šค์ณ๊ฐ€ ์—†๋Š” ์˜์—ญ์˜ ๊ฒฝ์šฐ minimum cost path๊ฐ€ ์œ ์ผํ•˜์ง€ ์•Š์•„ ๋ฌธ์ œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

Bayes matting ์‚ฌ์šฉ์ž๊ฐ€ ์ •์˜ํ•œ Trimap์„ ๋ฐ”ํƒ•์œผ๋กœ ํˆฌ๋ช…๋„๋ฅผ ๊ฐ–๋„๋ก ์ปฌ๋Ÿฌ ๋ถ„ํฌ๋ฅผ ๋ชจ๋ธ๋งํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์˜ ์•ˆ์ชฝ ์˜์—ญ๊ณผ ๋ฐ”๊นฅ ์˜์—ญ ์ž…๋ ฅ์˜ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

Knockout 2 Trimap์„ ์‚ฌ์šฉํ•˜๋Š” Bayes matting๊ณผ ๋น„์Šทํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

Graph Cut Bayes Matting๊ณผ trimap, ํ™•๋ฅ  ์ปฌ๋Ÿฌ ๋ชจ๋ธ์„ ๋ชจ๋‘ ๊ฐ–๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ํ›„์— ๋”ฐ๋กœ ์„ค๋ช…ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

Level sets ํŽธ๋ฏธ๋ถ„ ๋ฐฉ์ •์‹์„ ์ด์šฉํ•˜์—ฌ ์—๋„ˆ์ง€ ์ตœ์†Œํ™” ๋ฐฉ๋ฒ•์„ ํ†ตํ•˜์—ฌ ํ’€์–ด๋ƒ…๋‹ˆ๋‹ค. ์—๋„ˆ์ง€๋ฅผ ์ •์˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‚˜, ์ดˆ๊ธฐํ™” ๋ฐฉ๋ฒ•์— ๋”ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


์ € ํˆด๋“ค ์ค‘ Grabcut์€ ํŒŒ์ด์ฌ์— ์œ ์šฉํ•˜๊ฒŒ ์“ฐ์ด๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ผ๊ณ  ๋“ค์–ด์„œ Grabcut์„ ์กฐ์‚ฌํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.
GrabCut ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ด๋ฏธ์ง€์—์„œ ๋ฐฐ๊ฒฝ์ด ์•„๋‹Œ ์ „๊ฒฝ์— ํ•ด๋‹นํ•˜๋Š” ์ด๋ฏธ์ง€๋ฅผ ์ถ”์ถœํ•ด ๋‚ด๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

์ด๋ฏธ์ง€์—์„œ ํ•œ๋ฒˆ์— ์ „๊ฒฝ์„ ์ถ”์ถœํ•ด ๋‚ด๋Š” ๊ฒƒ์ด ์•„๋‹Œ ์‚ฌ์šฉ์ž์™€์˜ ์ƒํ˜ธ ์ž‘์šฉ์„ ํ†ตํ•ด ๋‹จ๊ณ„์ ์œผ๋กœ ์ „๊ฒฝ์„ ์ถ”์ถœํ•œ๋‹ค.

์ด ์ƒํ˜ธ์ž‘์šฉ์€ ํฌ๊ฒŒ 2๊ฐ€์ง€ ๋‹จ๊ณ„๋กœ ์ง„ํ–‰๋˜๋Š”๋ฐ,

์ฒซ๋ฒˆ์งธ๋Š” ์ด๋ฏธ์ง€์—์„œ ์ „๊ฒฝ์ด ํฌํ•จ๋˜๋Š” ์˜์—ญ์„ ์‚ฌ๊ฐํ˜•์œผ๋กœ ๋Œ€๋žต์ ์œผ๋กœ ์ง€์ •ํ•œ๋‹ค. ๋‹จ, ์ด๋•Œ ์ง€์ •ํ•œ ์‚ฌ๊ฐํ˜• ์˜์—ญ ์•ˆ์—๋Š” ์ „๊ฒฝ์ด ๋ชจ๋‘ ํฌํ•จ๋˜์–ด ์žˆ์–ด์•ผ ํ•œ๋‹ค.

๋‘๋ฒˆ์งธ๋Š” ์ฒซ๋ฒˆ์งธ์—์„œ ์–ป์–ด์ง„ ์ „๊ฒฝ ์ด๋ฏธ์ง€์˜ ๋‚ด์šฉ์ค‘ ํฌํ•จ๋˜์–ด์ง„ ๋ฐฐ๊ฒฝ ๋ถ€๋ถ„์€ ์–ด๋””์ธ์ง€, ๋ˆ„๋ฝ๋œ ์ „๊ฒฝ ๋ถ€๋ถ„์€ ์–ด๋””์ธ์ง€๋ฅผ ๋งˆํ‚นํ•˜๋ฉด ์ด๋ฅผ ์ด์šฉํ•ด ๋‹ค์‹œ ์ „๊ฒฝ ์ด๋ฏธ์ง€๊ฐ€ ์ƒˆ๋กญ๊ฒŒ ์ถ”์ถœ๋œ๋‹ค.

Grabcut์„ ์ด์šฉํ•˜์—ฌ ์•„๊นŒ contour๋กœ ์ „๊ฒฝ ๋ถ„๋ฆฌํ–ˆ๋˜ ์ด๋ฏธ์ง€๋ฅผ ๋‹ค์‹œํ•œ๋ฒˆ ๋ถ„๋ฆฌํ•ด๋ณด์•˜๋‹ค.

import numpy as np
import cv2 from matplotlib 
import pyplot as plt
img = cv2.imread('C:/Users/GhostDog/Desktop/myface.jpg')
mask = np.zeros(img.shape[:2] ,np.uint8)
bgdModel = np.zeros((1 ,65) ,np.float64)
fgdModel = np.zeros((1 ,65) ,np.float64)
rect = (50 ,50 ,1200 ,700)
cv2.grabCut(img ,mask ,rect ,bgdModel ,fgdModel ,5 ,cv2.GC_INIT_WITH_RECT)
mask2 = np.where((mask==2) |(mask==0) ,0 ,1).astype('uint8')
img = img *mask2[: ,: ,np.newaxis]plt.imshow(img) ,plt.colorbar() ,plt.show()

์•„๊นŒ๋ณด๋‹ค ํ›จ์”ฌ ์ „๊ฒฝ๋ถ„๋ฆฌ๊ฐ€ ์ž˜ ๋œ ๊ฒƒ์„ ๋ณผ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ƒ‰๊น”์ด ์–ด๋‘์›Œ์ง„ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ถ”ํ›„ ํ…Œ๋‘๋ฆฌ๋งŒ grabcut์œผ๋กœ ๋ถ„๋ฆฌํ•˜๊ณ  ์›๋ณธ ์ด๋ฏธ์ง€๋ฅผ ๋”ฐ์„œ ํ•ฉ์„ฑํ•˜๋ฉด ๋  ๊ฒƒ ๊ฐ™๋‹ค.


๋‹น์‹œ์— ์—ฌ๊ธฐ๊นŒ์ง€ ๋ณด๊ณ ์„œ๋ฅผ ๊ธฐ๋กํ–ˆ๋‹ค.

import numpy as np
import cv2

lowerBound = np.array([13, 155, 53])
upperBound = np.array([56, 216, 119])
##HSV ์ƒ‰์ƒ ์˜์—ญ์ด๋‹ค, ์›ํ•˜๋Š” ์ƒ‰์ƒ ์˜์—ญ์œผ๋กœ ๋ฐ”๊พธ๋ฉด ๋œ๋‹ค

def showcam():
    try:
        print ('open cam')
        cap = cv2.VideoCapture(0)
    except:
        print ('Not working')
    cap.set(3, 480)
    cap.set(4, 320)
 # try-except ๋ฌธ๋ฒ•์„ ์ด์šฉํ•ด ์บ ์ด ์•ˆ์—ด์˜€์„๋•Œ ์—๋Ÿฌ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค
    while True:
        ret, frame = cap.read()
        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
        #RGB -> HSV ๋ณ€ํ™˜
        color_mask = cv2.inRange(hsv, lowerBound, upperBound)
        #ํŠน์ • ์ƒ‰์ƒ ๋ฒ”์œ„ mask ์„ค์น˜
        ret1, thr = cv2.threshold(opening, 127, 255, 0)
        #contours ๋ฅผ ์ฐพ๊ธฐ์œ„ํ•œ ์ด์ง„ํ™”
        _, contours, _ = cv2.findContours(thr, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
        #contours์ฐพ๊ธฐ _,๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ธ์ž๋ผ์„œ '_'๋กœ ๋ฐ›๋Š”๋‹ค
        if len(contours) > 0:
            for i in range(len(contours)):
                area = cv2.contourArea(contours[i]) 
                #contours ์˜์—ญ ๊ตฌํ•˜๊ธฐ
                if area > 100:  # 100์ด์ƒ ์˜์—ญ์„ ๊ฐ€์ง„ ๋ฌผ์ฒด๊ฐ€ ์žˆ์„ ๋•Œ๋งŒ
                    rect = cv2.minAreaRect(contours[i])   #contours๋ฅผ ์ด์šฉํ•ด ์‚ฌ๊ฐํ˜•์„ ๋งŒ๋“ ๋‹ค
                    box = cv2.boxPoints(rect) #์‚ฌ๊ฐํ˜•์„ ์ฐพ์•„ 4์ ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
                    box = np.int0(box) 
                    cv2.drawContours(frame, [box], 0, (0, 0, 255), 2)   #์‚ฌ๊ฐํ˜• ๋ชจ์–‘์„ ๊ทธ๋ฆฐ๋‹ค
        if not ret:
            print('error')
            break
        cv2.imshow('color_bitwise',color_mask)
        cv2.imshow('cam_load',frame)
        k = cv2.waitKey(1) & 0xFF
        if k == 27:
            break

    cap.release()
    cv2.destroyAllWindows()
showcam()

Countour๋ฅผ ํ…Œ์ŠคํŠธํ•ด๋ณด๊ธฐ ์œ„ํ•ด ๋‹น์‹œ ์ด๋Ÿฐ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด๊ธฐ๋„ ํ–ˆ์—ˆ๊ณ 

๊ฐ–๊ฐ€์ง€ ์‹คํ—˜ ๋ชจ๋ธ๋กœ ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ๋ฅผ ์‹œ๋„ํ•ด๋ณด๊ธฐ๋„ ํ–ˆ์—ˆ๋‹ค.
๊ทธ๋ž˜์„œ ํ…์„œํ”Œ๋กœ์šฐ์™€ ์ผ€๋ผ์Šค๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ ๋‹ค์Œ ์–ผ๊ตด๊ณผ ์ „๊ฒฝ์„ ๋ถ„๋ฆฌํ•ด ๊ฐ์ •์— ๋”ฐ๋ฅธ ๋ฐฐ๊ฒฝ์„ ๊พธ๋ฏธ๊ฒŒ ํ–ˆ์—ˆ๋Š”๋ฐ ์ฝ”๋“œ๋ฅผ ์žƒ์–ด๋ฒ„๋ฆฐ ๊ฒƒ ๊ฐ™๋‹ค...


์œ„ ์‚ฌ์ง„์€ ๋‹น์‹œ์— img ํด๋”์— background_happy๊ฐ€ ์‚ฌ๋žŒ์˜ ๊ฐ์ •์„ happy๋กœ ์ธ์‹ํ•˜๋ฉด grabcut์„ ์ด์šฉํ•˜์—ฌ ์ „๊ฒฝ์„ ๋ถ„๋ฆฌํ•œ ๊ฑด๋ฐ..์–ด์งธ ๊ฒฐ๊ณผ๋ฌผ๋งŒ ์žˆ๊ณ  ์ฝ”๋“œ๊ฐ€ ์—†๋‹ค ใ…‹ใ…‹;
์–ด์จŒ๋“  ๋‚˜์˜ ์ขŒ์ถฉ์šฐ๋Œ ํ”„๋กœ์ ํŠธ๋Š” ์ด๋ ‡๊ฒŒ ๋์ด ๋‚ฌ๋‹ค.

์ถ”๊ฐ€๋กœ ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ์— ์ถ”๊ฐ€๋กœ ๋ผํ”Œ๋ผ์‹œ์•ˆ์— ๋Œ€ํ•ด ์กฐ์‚ฌํ–ˆ๋˜ ๋ณด๊ณ ์„œ๊ฐ€ ์žˆ์–ด ๊ฐ™์ด ์ฒจ๋ถ€ํ•œ๋‹ค.


1.๋ผํ”Œ๋ผ์‹œ์•ˆ์ด๋ž€?


์œ„์™€ ๊ฐ™์€ ์‹์„ ๋ผํ”Œ๋ผ์‹œ์•ˆ์ด๋ผ ์นญํ•จ

์œ„์™€ ๊ฐ™์€ ์‹์„ ๋ฏธ๋ถ„์—ฐ์‚ฐ์ž๋ผ ์นญํ•˜๋Š”๋ฐ, ๋ฒกํ„ฐ๋กœ ๋‚˜์˜ค๋Š” ๋ฏธ๋ถ„์—ฐ์‚ฐ์ž 2๊ฐœ๋ฅผ ์„œ๋กœ ๋‚ด์ ํ•˜๋ฉด ๋‚ด์ ์˜ ๊ฒฐ๊ณผ๋กœ ๊ฐ™์€ ์œ„์น˜๋ผ๋ฆฌ ๊ณฑ์˜ ํ•ฉ์ด ๋‚˜์˜ค๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Œ. (=๋ผํ”Œ๋ผ์‹œ์•ˆ)

์ด ์‹์˜ ๊ฒฐ๊ณผ๋กœ๋ถ€ํ„ฐ ๋ผํ”Œ๋ผ์‹œ์•ˆ์€ 2๋ฒˆ์˜ ํŽธ๋ฏธ๋ถ„์„ ํ•œ ๊ฒฐ๊ณผ๋กœ์จ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์–ด๋–ค ์Šค์นผ๋ผ ํ•จ์ˆ˜์— ๋Œ€ํ•˜์—ฌ ๋ผํ”Œ๋ผ์‹œ์•ˆ์„ ํ•˜๋Š” ๊ฒƒ์€, ์ˆœ์„œ๋Œ€๋กœ ๊ธฐ์šธ๊ธฐ๋ฅผ ๊ตฌํ•˜๊ณ  ๊ทธ๊ฒƒ์˜ ๋ฐœ์‚ฐ์„ ๊ตฌํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™๋‹ค. (=๊ธฐ์šธ๊ธฐ์˜ ๋ฐœ์‚ฐ)

โ€ป๋ผํ”Œ๋ผ์‹œ์•ˆ์˜ ์˜ˆ๋กœ ์ „์œ„์™€ ์ฒด์ ์ „ํ•˜๋ฐ€๋„์˜ ๊ด€๊ณ„๋ฅผ ์˜ˆ๋กœ ๋“ค ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ „์œ„์˜ ๋ผํ”Œ๋ผ์‹œ์•ˆ์€ ์ฒด์ ์ „ํ•˜ ๋ฐ€๋„๊ฐ€ ๋œ๋‹ค.

2.์˜์ƒ์ฒ˜๋ฆฌ์— ํ™œ์šฉ๋  ๋งŒํ•œ ๋ฐฉ๋ฒ•์€?

๋ผํ”Œ๋ผ์‹œ์•ˆ ๋ชจ์„œ๋ฆฌ ํ–ฅ์ƒ.
์ตœ์ „์— ๋Œ€ํ•œ ๋ณ€์ด๊ฐ€ ์—†๋Š” 2์ฐจ ๋„ํ•จ์ˆ˜ ํ˜•ํƒœ์˜ ํ•„ํ„ฐ. 1์ฐจํ•จ์ˆ˜์— ๊ธฐ์ดˆํ•œ ๊ทธ๋ ˆ๋””์–ธํŠธ์™€ ์ƒ๋ฐ˜๋œ ํ•„ํ„ฐ์ด๋‹ค.
๋จผ์ € ๊ทธ๋ ˆ๋””์–ธํŠธ๋ถ€ํ„ฐ ์„ค๋ช…์„ ํ•˜์ž๋ฉด, ์˜์ƒ์—์„œ ๊ธฐ์šธ๊ธฐ๋ฅผ gradient๋ผ ํ• ์‹œ ์ด gradient๋ฅผ ๊ตฌํ•˜๋ฉด edge๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค. ์˜์ƒ์—์„œ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์ผ์ • ๊ฐ„๊ฒฉ์œผ๋กœ ๋‚˜์—ด๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ˆ˜ํ•™์ ์ธ ๋ฏธ๋ถ„ ์˜์ƒ์„ ํ•˜์ง€ ์•Š์ง€๋งŒ, ์ธ์ ‘ํ•œ ํ™”์†Œ๋ผ๋ฆฌ์˜ ์ฐจ์ด๋ฅผ ์ทจํ•˜๋Š” ์—ฐ์‚ฐ์„ ํ•œ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๋ ˆ๋””์–ธํŠธ๊ฐ™์€ 1์ฐจ ๋ฏธ๋ถ„ ์—ฐ์‚ฐ์˜ ๊ฒฐ๊ณผ๋งŒ์œผ๋กœ๋Š” ๋„ˆ๋ฌด ๋งŽ์€ ์—์ง€ ํ›„๋ณด๋ฅผ ์ƒ์„ฑํ•˜๋ฏ€๋กœ, ๊ทธ๋ ˆ๋””์–ธํŠธ ๊ฐ‘์ด ๊ตญ์ง€์ ์œผ๋กœ ์ตœ๋Œ€์ธ ์ ๋งŒ์„ ์—์ง€๋กœ ์ธ์ •ํ•˜๋Š” ๊ฒƒ์„ 2์ฐจ ๋ฏธ๋ถ„ ์—ฐ์‚ฐ์ž๋ผ๊ณ  ํ•œ๋‹ค. ์‹ค์ œ ์—์ง€์ ์—์„œ๋Š” 1์ฐจ ๋ฏธ๋ถ„์ด ์ตœ๋Œ€๊ฐ€ ๋˜๊ณ , 2์ฐจ ๋ฏธ๋ถ„์ด ์˜์ ์„ ํ†ต๊ณผํ•˜๋Š” ์†์„ฑ์„ ์ด์šฉํ•˜์˜€๋‹ค๊ณ  ํ•œ๋‹ค.์œ„์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์„ 2์ฐจ ๋ฏธ๋ถ„์—ฐ์‚ฐ์ž, ์ฆ‰ ๋ผํ”Œ๋ผ์‹œ์•ˆ ์—ฐ์‚ฐ์ž๋ฅผ ๋„์ž…ํ–ˆ๋‹ค ์นญํ•œ๋‹ค.
๋ผํ”Œ๋ผ์‹œ์•ˆ์˜ ์ž ์ ์€ 2์ฐจ๋ฏธ๋ถ„์— ์˜ํ•œ ์—์ง€ ํŒ๋‹จ ์‹œ์ ์ด ์ œ๊ณต๋œ๋‹ค๋Š” ์ ์ด๋‹ค.
์„ฌ์„ธํ•œ ์—์ง€ ๊ฒ€์ถœ์€ ๋ฌผ๋Ÿฐ, ๋ชจ๋“  ๋ฐฉํ–ฅ์˜ ์—์ง€ ๊ฒ€์ถœ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์ ์—์„œ ํŽธํ•˜๋‹ค.
๊ทธ๋Ÿฌ๋‚˜, ์žก์Œ์— ๋ฏผ๊ฐํ•˜์—ฌ ์žก์Œ ์„ฑ๋ถ„๋˜ํ•œ ์˜์ƒ์— ๊ฐ•์กฐ๋  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ๊ฐ€์šฐ์Šคํ˜• ๋ผํ”Œ๋ผ์‹œ์•ˆ์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ๋ผํ”Œ๋ผ์‹œ์•ˆ์„ ์ ์šฉํ•˜๊ธฐ ์ „์— ์ „์ฒ˜๋ฆฌ ๋‹จ๊ณ„๋กœ ํ‰ํ™œํ™”๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค.

3.OPENCV๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌ๋™

import cv2import numpy as np
def ImageSobel(): imageFile = "C:/Users/JongMin/Desktop/myface.jpg"    
img = cv2.imread(imageFile,cv2.IMREAD_GRAYSCALE)    
Laplacian = cv2.Laplacian(img,-1)    
cv2.imshow("ORIGIN",img)    
cv2.imshow("Laplacain",Laplacian)    
cv2.waitKey(0)    
cv2.destroyAllWindows()ImageSobel()
profile
ํ•œ๋ฆผ๋Œ€ํ•™๊ต ์ •๋ณด๊ณผํ•™๋Œ€ 2ํ•™๋…„ ์žฌํ•™์ค‘ / ์œก๊ตฐ ์ •๋ณด๋ณดํ˜ธ๋ณ‘ 22-2๊ธฐ

0๊ฐœ์˜ ๋Œ“๊ธ€