Skip to content

Latest commit

ย 

History

History
354 lines (216 loc) ยท 20.1 KB

README_Korean.md

File metadata and controls

354 lines (216 loc) ยท 20.1 KB

Face Recognition

๋ณธ ๋ฌธ์„œ๋Š” _์ค‘๊ตญ์–ด ็ฎ€ไฝ“ไธญๆ–‡็‰ˆ ๋กœ๋ถ€ํ„ฐ ๋ฒˆ์—ญ๋˜์–ด ํ•œ๊ตญ ์‚ฌ์šฉ์ž๋“ค์˜ ๊ธฐ์—ฌ๋ฅผ ํ†ตํ•ด ๋งŒ๋“ค์–ด์ง„ ๋ฌธ์„œ์ž…๋‹ˆ๋‹ค.

๋ณธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์„ธ๊ณ„์—์„œ ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ์–ผ๊ตด ์ธ์‹ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, Python ๋˜๋Š” ๋ช…๋ น ์ค„(CLI)์—์„œ ์–ผ๊ตด์„ ์ธ์‹ํ•˜๊ณ  ์กฐ์ž‘ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ณธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๋”ฅ๋Ÿฌ๋‹ ๊ธฐ๋ฐ˜์œผ๋กœ ์ œ์ž‘๋œ dlib์˜ ์ตœ์ฒจ๋‹จ ์–ผ๊ตด ์ธ์‹ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์ถ•๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ชจ๋ธ์€ Labeled Faces in the Wild ๊ธฐ์ค€์œผ๋กœ 99.38%์˜ ์ •ํ™•๋„๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

๋˜ํ•œ, ๋ช…๋ น ์ค„(CLI)์—์„œ ์ด๋ฏธ์ง€ ํด๋” ์•ˆ์— ์žˆ๋Š” ์–ผ๊ตด ์ธ์‹ ๊ธฐ๋Šฅ์„ ์œ„ํ•œ ๊ฐ„๋‹จํ•œ face_recognition ๋„๊ตฌ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค!

PyPI Build Status Documentation Status

ํŠน์ง•

์‚ฌ์ง„์—์„œ ์–ผ๊ตด ์ฐพ๊ธฐ

์‚ฌ์ง„์— ๋“ฑ์žฅํ•˜๋Š” ๋ชจ๋“  ์–ผ๊ตด๋“ค์„ ์ฐพ์Šต๋‹ˆ๋‹ค:

import face_recognition
image = face_recognition.load_image_file("your_file.jpg")
face_locations = face_recognition.face_locations(image)

์‚ฌ์ง„์— ์žˆ๋Š” ์–ผ๊ตด์˜ ํŠน์ง•์„ ์ฐพ๊ธฐ&์กฐ์ž‘ํ•˜๊ธฐ

๊ฐ๊ฐ์˜ ์‚ฌ๋žŒ์˜ ๋ˆˆ, ์ฝ”, ์ž…, ํ„ฑ์˜ ์œ„์น˜์™€ ์œค๊ณฝ์„ ์žก์•„๋ƒ…๋‹ˆ๋‹ค.

import face_recognition
image = face_recognition.load_image_file("your_file.jpg")
face_landmarks_list = face_recognition.face_landmarks(image)

์–ผ๊ตด์˜ ํŠน์ง•์„ ์ฐพ๋Š” ๊ธฐ๋Šฅ์€ ์—ฌ๋Ÿฌ ์ค‘์š”ํ•œ ์ผ๋“ค์— ์œ ์šฉํ•˜๊ฒŒ ์“ฐ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋””์ง€ํ„ธ ๋ฉ”์ดํฌ์—… (Meitu ๊ฐ™์€ ๊ฒƒ)์„ ์ ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ์ •๋ง ๋ฉ์ฒญํ•œ ๊ฒƒ๋“ค์—๋„ ์“ฐ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

์‚ฌ์ง„ ์† ์–ผ๊ตด์˜ ์‹ ์› ํ™•์ธํ•˜๊ธฐ

๊ฐ๊ฐ์˜ ์‚ฌ์ง„์—์„œ ๋ˆ„๊ฐ€ ๋“ฑ์žฅํ•˜์˜€๋Š”์ง€ ์ธ์‹ํ•ฉ๋‹ˆ๋‹ค.

import face_recognition
known_image = face_recognition.load_image_file("biden.jpg")
unknown_image = face_recognition.load_image_file("unknown.jpg")

biden_encoding = face_recognition.face_encodings(known_image)[0]
unknown_encoding = face_recognition.face_encodings(unknown_image)[0]

results = face_recognition.compare_faces([biden_encoding], unknown_encoding)

์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋‹ค๋ฅธ Python ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์‹ค์‹œ๊ฐ„ ์–ผ๊ตด ์ธ์‹๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค:

์ฝ”๋“œ์— ๋Œ€ํ•ด์„œ๋Š” ์ด ์˜ˆ์ œ ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์˜จ๋ผ์ธ ๋ฐ๋ชจ

์‹ค์ œ ์‚ฌ์šฉ์ž๊ฐ€ ๊ณต์œ ํ•œ Jupyter notebook demo (๊ณต์‹์€ ์•„๋‹™๋‹ˆ๋‹ค): Deepnote

์„ค์น˜

์š”๊ตฌ ์‚ฌํ•ญ

  • Python 3.3+ ๋˜๋Š” Python 2.7
  • macOS ๋˜๋Š” Linux (Windows๋Š” ๊ณต์‹์ ์œผ๋กœ ์ง€์›ํ•˜์ง€ ์•Š์œผ๋‚˜, ์ž‘๋™ํ•  ์ˆ˜๋„ ์žˆ์Œ)

์„ค์น˜ ์˜ต์…˜๋“ค:

Mac ๋˜๋Š” Linux์—์„œ์˜ ์„ค์น˜

์šฐ์„ , Python ๋ฐ”์ธ๋”ฉ์„ ํ†ตํ•ด dlib์ด ์ด๋ฏธ ์„ค์น˜๊ฐ€ ๋˜์–ด์žˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:

๋‹ค์Œ์œผ๋กœ, pip3 (๋˜๋Š” Python2์˜ ๊ฒฝ์šฐ pip2)์„ ์‚ฌ์šฉํ•˜์—ฌ pypi์—์„œ์˜ ๋ชจ๋“ˆ์„ ์„ค์น˜ํ•˜์‹ญ์‹œ์˜ค:

pip3 install face_recognition

๋˜๋Š”, ์ด ๋ถ€๋ถ„์„ ์ฐธ์กฐํ•˜์—ฌ, Docker๋กœ ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‹œ๋„ํ•ด๋ณด์‹ญ์‹œ์˜ค.

์„ค์น˜์— ๋Œ€ํ•ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€์œผ๋ฉด, ๋ฏธ๋ฆฌ ๊ตฌ์„ฑ๋œ VM์„ ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

Raspberry Pi 2+์—์„œ์˜ ์„ค์น˜

Windows์—์„œ ์„ค์น˜ํ•˜๊ธฐ

Windows๋Š” ๊ณต์‹์ ์œผ๋กœ ์ง€์›ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ, ์นœ์ ˆํ•œ ์œ ์ €๋“ค์ด ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์–ด๋–ป๊ฒŒ ์„ค์น˜ํ•˜๋Š”์ง€ ์„ค๋ช…์„œ๋ฅผ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค:

๋ฏธ๋ฆฌ ๊ตฌ์„ฑ๋œ ๊ฐ€์ƒ๋จธ์‹  ์ด๋ฏธ์ง€(VM)๋ฅผ ์„ค์น˜ํ•˜๊ธฐ

์‚ฌ์šฉ๋ฒ•

๋ช…๋ น ์ค„ ์ธํ„ฐํŽ˜์ด์Šค

face_recognition์„ ์„ค์น˜ํ•˜๋ฉด, ๋‘ ๊ฐ€์ง€ ๊ฐ„๋‹จํ•œ ๋ช…๋ น ์ค„(CLI) ํ”„๋กœ๊ทธ๋žจ์„ ์–ป์Šต๋‹ˆ๋‹ค:

  • face_recognition - ์‚ฌ์ง„ ํ˜น์€ ์‚ฌ์ง„์ด ๋“ค์–ด์žˆ๋Š” ํด๋”์—์„œ, ์–ผ๊ตด์„ ์ธ์‹ํ•ฉ๋‹ˆ๋‹ค.
  • face_detection - ์‚ฌ์ง„ ํ˜น์€ ์‚ฌ์ง„์ด ๋“ค์–ด์žˆ๋Š” ํด๋”์—์„œ, ์–ผ๊ตด์„ ์ฐพ์Šต๋‹ˆ๋‹ค.

face_recognition ๋ช…๋ น ์ค„ ๋„๊ตฌ

face_recognition ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜๋ฉด ์‚ฌ์ง„ ํ˜น์€ ์‚ฌ์ง„์ด ๋“ค์–ด์žˆ๋Š” ํด๋”์—์„œ, ์–ผ๊ตด์„ ์ธ์‹ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋จผ์ €, ์ด๋ฏธ ์•Œ๊ณ  ์žˆ๋Š”(์ธ์‹ํ•˜๊ณ ์ž ํ•˜๋Š”) ๊ฐ ์‚ฌ๋žŒ์˜ ์‚ฌ์ง„ ํ•œ ์žฅ์ด ํด๋”์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์‚ฌ์ง„ ์† ๊ทธ ์‚ฌ๋žŒ์˜ ์ด๋ฆ„์„ ๋”ด ์ด๋ฏธ์ง€ ํŒŒ์ผ์ด ๊ฐ๊ฐ ํ•˜๋‚˜์”ฉ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:

known

๋‹ค์Œ์œผ๋กœ, ์‹๋ณ„ํ•˜๊ณ  ์‹ถ์€ ํŒŒ์ผ๋“ค์ด ์žˆ๋Š” ๋‘ ๋ฒˆ์งธ ํด๋”๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค:

unknown

๊ทธ๋Ÿฐ ๋‹ค์Œ, ์•Œ๊ณ  ์žˆ๋Š” ์‚ฌ๋žŒ์˜ ํด๋”์™€ ๋ชจ๋ฅด๋Š” ์‚ฌ๋žŒ์˜ ํด๋”(๋˜๋Š” ๋‹จ์ผ ์ด๋ฏธ์ง€)๋ฅผ ์ „๋‹ฌํ•˜๋Š” face_recognition ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋ฉด, ๊ฐ ์ด๋ฏธ์ง€์— ์žˆ๋Š” ์‚ฌ๋žŒ์ด ๋ˆ„๊ตฐ์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

$ face_recognition ./pictures_of_people_i_know/ ./unknown_pictures/

/unknown_pictures/unknown.jpg,Barack Obama
/face_recognition_test/unknown_pictures/unknown.jpg,unknown_person

๊ฐ๊ฐ์˜ ์–ผ๊ตด์˜ ๊ฒฐ๊ณผ๋Š” ํ•œ ์ค„๋กœ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ๊ฐ ์ค„์€ ํŒŒ์ผ ์ด๋ฆ„๊ณผ ์‹๋ณ„๋œ ๊ฒฐ๊ณผ์ธ ์‚ฌ๋žŒ ์ด๋ฆ„์ด ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„๋˜์–ด ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

unknown_person์€ ์ด๋ฏธ์ง€ ์†์— ์•Œ๊ณ  ์žˆ๋Š” ์‚ฌ๋žŒ์˜ ํด๋”์— ์žˆ๋Š” ๊ทธ ๋ˆ„๊ตฌ์™€๋„ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š” ์–ผ๊ตด์ž„์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

face_detection ๋ช…๋ น ์ค„ ๋„๊ตฌ

face_detection ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋ฏธ์ง€์—์„œ ์–ผ๊ตด์˜ ์œ„์น˜ (ํ”ฝ์…€ ์ขŒํ‘œ)๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

face_detection ๋ช…๋ น์„ ์‹คํ–‰ํ•˜์—ฌ ๊ฒ€์‚ฌ ํ•  ์ด๋ฏธ์ง€ ํด๋” (๋˜๋Š” ๋‹จ์ผ ์ด๋ฏธ์ง€)๋ฅผ ์ „๋‹ฌํ•˜์‹ญ์‹œ์˜ค:

$ face_detection  ./folder_with_pictures/

examples/image1.jpg,65,215,169,112
examples/image2.jpg,62,394,211,244
examples/image2.jpg,95,941,244,792

๊ฐ์ง€๋œ ๊ฐ ์–ผ๊ตด์— ๋Œ€ํ•ด ํ•œ ์ค„์”ฉ ์ธ์‡„ํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ๊ฐ’์˜ ์ขŒํ‘œ๋Š” ๊ฐ๊ฐ ์–ผ๊ตด์˜ ์œ„์ชฝ, ์˜ค๋ฅธ์ชฝ, ์•„๋ž˜์ชฝ ๋ฐ ์™ผ์ชฝ ์ขŒํ‘œ (ํ”ฝ์…€ ๋‹จ์œ„)์ž…๋‹ˆ๋‹ค.

์˜ค์ฐจ ์กฐ์ ˆ / ๋ฏผ๊ฐ๋„

๊ฐ™์€ ์‚ฌ๋žŒ์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ•ญ๋ชฉ์„ ์–ป์—ˆ๋‹ค๋ฉด, ์‚ฌ์ง„์— ์žˆ๋Š” ์‚ฌ๋žŒ๋“ค์ด ๋งค์šฐ ์œ ์‚ฌํ•˜๊ฒŒ ๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์ด๋ฉฐ ๋”์šฑ ์—„๊ฒฉํ•œ ์–ผ๊ตด ๋น„๊ต๋ฅผ ์œ„ํ•ด ๋‚ฎ์€ ํ—ˆ์šฉ์น˜(tolerance value)๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

--tolerance ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ์ด๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ํ—ˆ์šฉ์น˜ ๊ฐ’์€ 0.6์ด๋ฉฐ ์ˆซ์ž๊ฐ€ ๋‚ฎ์œผ๋ฉด ๋”์šฑ ์—„๊ฒฉํ•œ ์–ผ๊ตด ๋น„๊ต๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค:

$ face_recognition --tolerance 0.54 ./pictures_of_people_i_know/ ./unknown_pictures/

/unknown_pictures/unknown.jpg,Barack Obama
/face_recognition_test/unknown_pictures/unknown.jpg,unknown_person

ํ—ˆ์šฉ์น˜ ์„ค์ •์„ ์กฐ์ •ํ•˜๊ธฐ ์œ„ํ•ด, ๊ฐ ์‹๋ณ„์—์„œ์˜ ์–ผ๊ตด ๊ฑฐ๋ฆฌ๋ฅผ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด --show-distance true๋ฅผ ํ†ตํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

$ face_recognition --show-distance true ./pictures_of_people_i_know/ ./unknown_pictures/

/unknown_pictures/unknown.jpg,Barack Obama,0.378542298956785
/face_recognition_test/unknown_pictures/unknown.jpg,unknown_person,None
๋” ๋งŽ์€ ์˜ˆ์ œ๋“ค

ํŒŒ์ผ ์ด๋ฆ„์€ ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š๊ณ  ๊ฐ ์‚ฌ์ง„์— ์žˆ๋Š” ์‚ฌ๋žŒ๋“ค์˜ ์ด๋ฆ„๋งŒ์„ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

$ face_recognition ./pictures_of_people_i_know/ ./unknown_pictures/ | cut -d ',' -f2

Barack Obama
unknown_person
์–ผ๊ตด ์ธ์‹ ์†๋„ ํ–ฅ์ƒ

์—ฌ๋Ÿฌ ๊ฐœ์˜ CPU ์ฝ”์–ด๊ฐ€ ์žˆ๋Š” ์ปดํ“จํ„ฐ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ์–ผ๊ตด ์ธ์‹์„ ๋™์‹œ์— ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด, 4๊ฐœ์˜ CPU ์ฝ”์–ด๊ฐ€ ์žˆ๋Š” ํ™˜๊ฒฝ์—์„œ๋Š”, ๋ชจ๋“  CPU ์ฝ”์–ด๋ฅผ ๋ณ‘๋ ฌ๋กœ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ™์€ ์‹œ๊ฐ„ ๋™์•ˆ ์•ฝ 4๋ฐฐ์˜ ์ด๋ฏธ์ง€๋“ค์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Python 3.4 ์ด์ƒ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ --cpus <number_of_cpu_cores_to_use> ์— ๋งค๊ฐœ ๋ณ€์ˆ˜(parameter)๋ฅผ ์ „๋‹ฌํ•˜์‹ญ์‹œ์˜ค:

$ face_recognition --cpus 4 ./pictures_of_people_i_know/ ./unknown_pictures/

๋˜ํ•œ --cpus -1์„ ์ „๋‹ฌํ•˜์—ฌ ์‹œ์Šคํ…œ์˜ ๋ชจ๋“  CPU ์ฝ”์–ด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

Python ๋ชจ๋“ˆ

face_recognition ๋ชจ๋“ˆ์„ ๋ถˆ๋Ÿฌ์™€(import) ๋‹จ ๋ช‡ ์ค„์˜ ์ฝ”๋“œ๋งŒ์œผ๋กœ ์–ผ๊ตด ์กฐ์ž‘์„ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋งค์šฐ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค!

API ๋ฌธ์„œ: https://face-recognition.readthedocs.io.

์ด๋ฏธ์ง€์˜ ๋ชจ๋“  ์–ผ๊ตด์„ ์ž๋™์œผ๋กœ ์ฐพ๊ธฐ
import face_recognition

image = face_recognition.load_image_file("my_picture.jpg")
face_locations = face_recognition.face_locations(image)

# face_locations is now an array listing the co-ordinates of each face!

์ด ์˜ˆ์ œ ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ ํ•ด ๋ณด์‹ญ์‹œ์˜ค.

์ข€ ๋” ์ •ํ™•ํ•œ ๋”ฅ ๋Ÿฌ๋‹ ๊ธฐ๋ฐ˜์˜ ์–ผ๊ตด ํƒ์ง€ ๋ชจ๋ธ์„ ์ฑ„ํƒํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ : ์ด ๋ชจ๋ธ์˜ ์„ฑ๋Šฅ์„ ๋†’์ด๋ ค๋ฉด (NVidia์˜ CUDA ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•œ) GPU ๊ฐ€์†์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ dlib์„ ์ปดํŒŒ์ผ๋งํ•  ๋•Œ CUDA ์ง€์›(support)์„ ํ™œ์„ฑํ™” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import face_recognition

image = face_recognition.load_image_file("my_picture.jpg")
face_locations = face_recognition.face_locations(image, model="cnn")

# face_locations is now an array listing the co-ordinates of each face!

์ด ์˜ˆ์ œ ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ ํ•ด ๋ณด์‹ญ์‹œ์˜ค.

์ด๋ฏธ์ง€์™€ GPU๊ฐ€ ๋‘˜ ๋‹ค ๋งŽ์€ ๊ฒฝ์šฐ, ์–ผ๊ตด์„ ์ผ๊ด„์ ์œผ๋กœ ์ฐพ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฏธ์ง€์—์„œ ์ž๋™์œผ๋กœ ์‚ฌ๋žŒ์˜ ์–ผ๊ตด ํŠน์ง• ์ฐพ๊ธฐ
import face_recognition

image = face_recognition.load_image_file("my_picture.jpg")
face_landmarks_list = face_recognition.face_landmarks(image)

# face_landmarks_list is now an array with the locations of each facial feature in each face.
# face_landmarks_list[0]['left_eye'] would be the location and outline of the first person's left eye.

์ด ์˜ˆ์ œ ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ ํ•ด ๋ณด์‹ญ์‹œ์˜ค.

์ด๋ฏธ์ง€์—์„œ ์–ผ๊ตด์„ ์ธ์‹ํ•˜๊ณ  ๋ˆ„๊ตฌ์ธ์ง€ ์‹๋ณ„ํ•˜๊ธฐ
import face_recognition

picture_of_me = face_recognition.load_image_file("me.jpg")
my_face_encoding = face_recognition.face_encodings(picture_of_me)[0]

# my_face_encoding์€ ์ด์ œ ์–ด๋Š ์–ผ๊ตด๊ณผ๋„ ๋น„๊ตํ•  ์ˆ˜ ์žˆ๋Š” ๋‚ด๊ฐ€ ๊ฐ€์ง„ ์–ผ๊ตด ํŠน์ง•์˜ ๋ณดํŽธ์ ์ธ ์ธ์ฝ”๋”ฉ์„ ํฌํ•จํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. 

unknown_picture = face_recognition.load_image_file("unknown.jpg")
unknown_face_encoding = face_recognition.face_encodings(unknown_picture)[0]

# ์ด์ œ `compare_faces`๋ฅผ ํ†ตํ•ด ๋‘ ์–ผ๊ตด์ด ๊ฐ™์€ ์–ผ๊ตด์ธ์ง€ ๋น„๊ตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

results = face_recognition.compare_faces([my_face_encoding], unknown_face_encoding)

if results[0] == True:
    print("It's a picture of me!")
else:
    print("It's not a picture of me!")

์ด ์˜ˆ์ œ ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ ํ•ด ๋ณด์‹ญ์‹œ์˜ค.

Python ์ฝ”๋“œ ์˜ˆ์ œ

๋ชจ๋“  ์˜ˆ์ œ๋Š” ์—ฌ๊ธฐ ์— ์žˆ์Šต๋‹ˆ๋‹ค.

์–ผ๊ตด ํƒ์ง€

์–ผ๊ตด์˜ ํŠน์ง•

์–ผ๊ตด ์ธ์‹

๋…๋ฆฝ์ ์ธ ์‹คํ–‰ ํŒŒ์ผ ๋งŒ๋“ค๊ธฐ

Python์ด๋‚˜ face_recognition์„ ์„ค์น˜ํ•  ํ•„์š” ์—†์ด ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋…๋ฆฝ์ ์ธ ์‹คํ–‰ํ˜• ์‹คํ–‰ ํŒŒ์ผ์„ ๋งŒ๋“ค๋ ค๋ฉด PyInstaller ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜, ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์ž‘์—…ํ•˜๋ ค๋ฉด ์–ด๋Š ์ •๋„์˜ ์„ค์ • ์ปค์Šคํ…€์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ๋Š” ์ด ์ด์Šˆ ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

face_recognition์„ ๋‹ค๋ฃจ๋Š” ๊ธ€ ๋ฐ ๊ฐ€์ด๋“œ

์–ผ๊ตด ์ธ์‹์ด ์ž‘๋™ํ•˜๋Š”์ง€

black box ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์˜์กดํ•˜๋Š” ๋Œ€์‹  ์–ผ๊ตด ์œ„์น˜์™€ ์ธ์‹์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ์•Œ๊ณ  ์‹ถ์œผ์‹œ๋‹ค๋ฉด ์ด ๊ธ€ ์„ ์ฝ์œผ์‹ญ์‹œ์˜ค.

์ฃผ์˜ ์‚ฌํ•ญ

  • ์–ผ๊ตด ์ธ์‹์˜ ๋ชจ๋ธ์€ ์„ฑ์ธ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ํ†ตํ•ด ํ›ˆ๋ จ์ด ๋˜์—ˆ์œผ๋ฉฐ ๋”ฐ๋ผ์„œ ์–ด๋ฆฐ์ด์˜ ๊ฒฝ์šฐ์—๋Š” ์ž˜ ์ ์šฉ์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. 0.6์˜ ๊ธฐ๋ณธ ์ž„๊ณ„ ๊ฐ’์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์–ด๋ฆฐ์ด๋“ค์˜ ์–ผ๊ตด์„ ๊ตฌ๋ถ„ํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒฝํ–ฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์†Œ์ˆ˜ ๋ฏผ์กฑ๋งˆ๋‹ค ์ •ํ™•์„ฑ์ด ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ด ์œ„ํ‚ค ํŽ˜์ด์ง€ ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

face_recognition์€ C++๋กœ ์ž‘์„ฑ๋œ dlib์— ์˜์กดํ•˜๊ธฐ ๋•Œ๋ฌธ์—, Heroku ๋˜๋Š” AWS์™€ ๊ฐ™์€ ํด๋ผ์šฐ๋“œ ํ˜ธ์ŠคํŒ… ์ œ๊ณต ์—…์ฒด์— ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์•ฑ์„ ๋ฐฐํฌํ•˜๋Š” ๊ฒƒ์€ ๊นŒ๋‹ค๋กœ์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋” ์‰ฌ์šด ์ž‘์—…์„ ์œ„ํ•ด, Docker container์—์„œ face_recognition์œผ๋กœ ๋นŒ๋“œ ๋œ ์•ฑ์„ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ฃผ๋Š” ์ด repo์˜ Dockerfile ์˜ˆ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด Docker ์ด๋ฏธ์ง€๋ฅผ ์ง€์›ํ•˜๋Š” ๋ชจ๋“  ์„œ๋น„์Šค์— ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์„ ์‹คํ–‰ํ•˜์—ฌ Docker ์ด๋ฏธ์ง€๋ฅผ ๋กœ์ปฌ๋กœ ์‹œ๋„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: docker-compose up --build

GPU (๋“œ๋ผ์ด๋ฒ„ >= 384.81) ๋ฐ Nvidia-Docker ๊ฐ€ ์„ค์น˜๋œ Linux ์‚ฌ์šฉ์ž๋Š” GPU์—์„œ ์˜ˆ์ œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: docker-compose.yml ํŒŒ์ผ์„ ์—ด๊ณ  dockerfile : Dockerfile.gpu ๋ฐ runtime : nvidia ํ–‰์˜ ์ฃผ์„ ์ฒ˜๋ฆฌ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์ œ๊ฐ€ ์žˆ์œผ์‹ญ๋‹ˆ๊นŒ?

๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด github ๋ฌธ์ œ๋ฅผ ์ œ๊ธฐํ•˜๊ธฐ ์ „์— ์œ„ํ‚ค์˜ ์ผ๋ฐ˜์ ์ธ ์˜ค๋ฅ˜ ์„น์…˜์„ ์ฝ์–ด๋ณด์‹ญ์‹œ์˜ค.

๊ฐ์‚ฌ์˜ ๋ง

  • dlib๋ฅผ ๋งŒ๋“ค๊ณ  ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์‚ฌ์šฉ๋œ ์–ผ๊ตด ์ธ์‹ ๊ธฐ๋Šฅ๊ณผ ์–ผ๊ตด ์ธ์ฝ”๋”ฉ ๋ชจ๋ธ์„ ์ œ๊ณตํ•œ Davis King (@nulhom) ์—๊ฒŒ ๋งŽ์€ ๊ฐ์‚ฌ๋ฅผ ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ์–ผ๊ตด ์ธ์ฝ”๋”ฉ์„ ์ง€์›ํ•˜๋Š” ResNet์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ ์„ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.
  • numpy, scipy, scikit-image, pillow ๋“ฑ์˜ ๋ชจ๋“  ๋ฉ‹์ง„ ํŒŒ์ด์ฌ ๋ฐ์ดํ„ฐ ๊ณผํ•™ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ผํ•˜๋Š” ๋ชจ๋“  ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ๊ฒƒ๋“ค์„ ํŒŒ์ด์ฌ์—์„œ ์‰ฝ๊ณ  ์žฌ๋ฏธ์žˆ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  • Cookiecutter ์™€ audreyr/cookiecutter-pypackage ํ”„๋กœ์ ํŠธ ํ…œํ”Œ๋ฆฟ ๋•๋ถ„์— ํŒŒ์ด์ฌ ํ”„๋กœ์ ํŠธ ํŒจํ‚ค์ง• ๋ฐฉ์‹์ด ๋” ๊ดœ์ฐฎ์•„ ์กŒ์Šต๋‹ˆ๋‹ค.