A.I
Explolation7 닮은 꼴 연예인 찾기 본문
1. 임베딩이란?¶
- 고차원 정보를 저차원으로 변환하면서 필요한 정보를 보존하는 것
임베딩 공간에서 의미적으로 비슷한 입력 사항들을 가깝게 배치함으로써 입력에 포함된 의미 중 일부를 포착하는 것
2. 얼굴 인식¶
- 이미지 속에서 얼굴 영역만을 정확하게 인식해서 추출
- Input image - Detection - Transform - Crop과정을 거침
2-1. dlib을 이용한 추출¶
- HOG(Histogram of Oriented Gradient) feature를 사용해서 SVM(Support Vector Machine)의 sliding window로 얼굴을 찾는 face detector 기능을 제공
- dlib 설치
pip install cmake
pip install dlib
pip install face_recognition - 인식할 이미지 저장
mkdir -p ~/aiffel/face_embedding/images
wget https://aiffelstaticprd.blob.core.windows.net/media/documents/biden.jpg
wget https://aiffelstaticprd.blob.core.windows.net/media/documents/bush.jpeg
wget https://aiffelstaticprd.blob.core.windows.net/media/documents/clinton.jpeg
wget https://aiffelstaticprd.blob.core.windows.net/media/documents/obama.jpg
wget https://aiffelstaticprd.blob.core.windows.net/media/documents/reagan.jpg
wget https://aiffelstaticprd.blob.core.windows.net/media/documents/trump.jpg
mv biden.jpg bush.jpeg clinton.jpeg obama.jpg reagan.jpg trump.jpg ~/aiffel/face_embedding/images
In [107]:
import face_recognition
import os
image_path = os.getenv('HOME')+'/aiffel/face_embedding/images/obama.jpg'
image = face_recognition.load_image_file(image_path)
face_locations = face_recognition.face_locations(image)
print(face_locations) # 이미지에서 얼굴 영역의 좌표를 출력합니다.
%matplotlib inline
import matplotlib.pyplot as plt
a, b, c, d = face_locations[0]
cropped_face = image[a:c,d:b,:]
plt.imshow(cropped_face) # 이미지에서 얼굴영역만 잘라낸 cropped_face를 그려 봅니다.
[(98, 758, 284, 572)]
Out[107]:
<matplotlib.image.AxesImage at 0x7f9e91a65a10>
In [108]:
# 얼굴 추출용 메서드
import face_recognition
import os
def get_gropped_face(image_file):
image = face_recognition.load_image_file(image_file)
face_locations = face_recognition.face_locations(image)
a, b, c, d = face_locations[0]
cropped_face = image[a:c,d:b,:]
return cropped_face
In [114]:
image_path = os.getenv('HOME')+'/aiffel/face_embedding/images/trump.jpg'
cropped_face = get_gropped_face(image_path)
plt.imshow(cropped_face)
Out[114]:
<matplotlib.image.AxesImage at 0x7f9e9193ab90>
3. FaceNet¶
- TripleLoss란 같은 사람의 임베딩 벡터 A-C간의 거리를 가깝게 그리고 다른 사람의 임베딩 벡터 B-C간의 거리를 멀게 학습 시켜 같은 사람의 얼굴에서 나온 임베딩이 멀리 배치된다면 학습을 통해서 가까워지도록 임베딩 벡터를 만들어 내는 것
In [121]:
import os
dir_path = os.getenv('HOME')+'/aiffel/face_embedding/images'
file_list = os.listdir(dir_path)
print ("file_list: {}".format(file_list))
file_list: ['reagan.jpg', 'bush.jpeg', 'msb1.jpg', 'biden.jpg', 'clinton.jpeg', 'trump.jpg', 'obama.jpg', 'msb2.jpg']
In [122]:
image_file = os.path.join(dir_path, 'obama.jpg')
face = get_gropped_face(image_file) # 얼굴 영역을 구하는 함수(이전 스텝에서 구현)
# 얼굴 영역을 가지고 얼굴 임베딩 벡터를 구하는 함수
def get_face_embedding(face):
return face_recognition.face_encodings(face)
embedding = get_face_embedding(face)
embedding
Out[122]:
[array([-0.08126248, 0.11014761, -0.01082448, -0.05268792, 0.01033717, -0.00813808, -0.07251769, -0.0922646 , 0.19304723, -0.09246384, 0.23908533, 0.06770287, -0.22123125, -0.14119367, 0.05562152, 0.13705511, -0.17924425, -0.07232306, -0.11183281, -0.11370818, 0.03956435, -0.01019115, 0.0942178 , 0.04493114, -0.12757549, -0.34449592, -0.05374938, -0.17703305, 0.00868226, -0.09721592, -0.09817187, 0.00278232, -0.17721367, -0.12789807, 0.03489833, -0.01991234, -0.00838933, -0.00132862, 0.18308581, 0.02447568, -0.1237656 , 0.09957044, 0.02323568, 0.22983313, 0.2838524 , 0.06655717, -0.00558912, -0.09833544, 0.10058986, -0.23476946, 0.06006292, 0.1341591 , 0.08373027, 0.03900504, 0.10194533, -0.19337648, 0.01717628, 0.08978969, -0.16005114, 0.01892098, 0.03082444, -0.06051281, -0.04526773, 0.04633342, 0.20678686, 0.10299795, -0.12437531, -0.0490516 , 0.12252682, -0.0280379 , 0.04286709, 0.01386448, -0.18673278, -0.22230086, -0.23382807, 0.07662997, 0.3739067 , 0.18993473, -0.20606737, 0.0244521 , -0.18487695, 0.04949443, 0.09670059, -0.00123947, -0.0688749 , -0.13414779, -0.04103697, 0.06179445, 0.07108597, 0.02471443, -0.04194992, 0.22575834, -0.02099216, 0.04838851, 0.02123774, 0.05604827, -0.14657559, -0.02243515, -0.17425998, -0.06527615, 0.02526723, -0.04892462, 0.05058879, 0.13397783, -0.23065181, 0.06054964, 0.02031171, -0.0191126 , 0.03631671, 0.06983903, -0.03496742, -0.03203756, 0.05493437, -0.24500111, 0.24993542, 0.24442896, 0.04081136, 0.16412377, 0.06019448, 0.0062465 , -0.00932551, -0.02752422, -0.17775527, -0.03611944, 0.04782868, 0.06031797, 0.06846569, 0.00587987])]
In [123]:
# images 디렉토리 안에 있는 모든 이미지 파일의 임베딩을 구해서 dict 구조에 담아 리턴하는 함수
def get_face_embedding_dict(dir_path):
file_list = os.listdir(dir_path)
embedding_dict = {}
for file in file_list:
img_path = os.path.join(dir_path, file)
face = get_gropped_face(img_path)
embedding = get_face_embedding(face)
if len(embedding) > 0: # 얼굴영역 face가 제대로 detect되지 않으면 len(embedding)==0인 경우가 발생하므로
# os.path.splitext(file)[0]에는 이미지파일명에서 확장자를 제거한 이름이 담깁니다.
embedding_dict[os.path.splitext(file)[0]] = embedding[0]
return embedding_dict
In [124]:
embedding_dict = get_face_embedding_dict(dir_path)
embedding_dict['trump']
Out[124]:
array([-0.15962467, 0.20268655, 0.0323635 , 0.02439232, -0.06226439, 0.05140705, 0.07351795, -0.16823348, 0.06962204, -0.05557961, 0.17270109, -0.05094168, -0.35293093, -0.0316438 , 0.03792984, 0.17343847, -0.13260126, -0.15357377, -0.23523533, -0.08442692, -0.00134139, 0.03210667, -0.08926154, -0.02670781, -0.09581181, -0.25792354, -0.01056999, -0.11071672, 0.03133569, -0.07444921, 0.05670552, -0.02273796, -0.19461137, -0.04576054, 0.00947582, 0.01806056, -0.1502624 , -0.07787319, 0.17577608, 0.01933258, -0.19744575, -0.03930519, 0.07374467, 0.20196027, 0.1476755 , -0.0141539 , 0.0172476 , -0.11976205, 0.09462971, -0.24318144, -0.02755127, 0.12169892, 0.14837705, 0.17079785, 0.06952555, -0.15360466, 0.02005427, 0.08199155, -0.19544823, 0.10653654, 0.11468476, -0.21902837, -0.07677591, -0.06791042, 0.10587606, 0.05921567, -0.06115703, -0.11171092, 0.23917492, -0.15791436, -0.13834007, 0.01942121, 0.01826206, -0.1869376 , -0.32023543, 0.01407088, 0.34068239, 0.20081407, -0.19736893, -0.06809217, -0.0536031 , -0.03747801, 0.07641605, 0.09667511, -0.04759219, -0.09811257, -0.05056169, -0.01899303, 0.24124743, -0.04360487, 0.00636286, 0.21936756, 0.01126812, -0.04524586, -0.00227514, 0.02113587, -0.11754515, -0.05986457, -0.08348871, -0.07204333, -0.00065423, -0.14080839, 0.03825339, 0.08760153, -0.11946712, 0.18282008, 0.03533202, 0.01670191, -0.00815773, -0.00964593, -0.06726068, 0.01727787, 0.16389623, -0.16469438, 0.25836599, 0.20883362, -0.0511426 , 0.0673226 , 0.11310361, 0.08522274, -0.01515304, -0.03709226, -0.22167102, -0.18071674, 0.06958843, 0.02523582, -0.01741696, 0.03869874])
4. 얼굴 임베딩 사이의 거리 측정¶
In [8]:
import numpy as np
A = np.array([0.0019173615146428347, 0.17689529061317444, 0.0763588473200798, -0.024574430659413338, -0.13141091167926788, 0.0344821996986866, -0.0374063216149807, -0.07056370377540588, 0.048655178397893906, -0.03414120525121689, 0.22696012258529663, -0.061402369290590286, -0.24329672753810883, -0.039421431720256805, 0.0621466189622879, 0.1220191940665245, -0.1616966724395752, -0.06176016479730606, -0.18894734978675842, -0.06051916256546974, -0.010404378175735474, -0.05918719246983528, 0.02205268107354641, -0.06932859122753143, -0.20260301232337952, -0.2425234317779541, -0.04454419016838074, -0.11400106549263, -0.02022719383239746, -0.15134216845035553, 0.07622595876455307, -0.0323314443230629, -0.1404413878917694, -0.056338660418987274, -0.04520038887858391, -0.026131991297006607, -0.0352761372923851, -0.0679447203874588, 0.1318240910768509, 0.034210119396448135, -0.17475582659244537, 0.13853909075260162, -0.0027398746460676193, 0.227312833070755, 0.3029572069644928, 0.004932125099003315, 0.05853061378002167, -0.07521739602088928, 0.1443275809288025, -0.2340908795595169, 0.030092637985944748, 0.040133409202098846, 0.1672351360321045, 0.05728958174586296, 0.11475440859794617, -0.07548368722200394, 0.040267568081617355, 0.16487033665180206, -0.21067440509796143, 0.036163005977869034, 0.051559075713157654, -0.05994952470064163, 0.029524143785238266, -0.04122130945324898, 0.13074155151844025, 0.1142958477139473, -0.00561982998624444, -0.09740489721298218, 0.18533651530742645, -0.10422169417142868, -0.11409182846546173, 0.02283927984535694, -0.08339140564203262, -0.13673236966133118, -0.3275497853755951, -0.0002689119428396225, 0.2842463254928589, 0.13883619010448456, -0.29149484634399414, -0.07276060432195663, -0.03179163485765457, 0.011192545294761658, 0.03802505508065224, 0.03392524644732475, -0.03972085565328598, -0.12013585865497589, -0.06272879987955093, -0.026893358677625656, 0.2430601865053177, -0.12022019177675247, -0.010466678068041801, 0.20199882984161377, 0.051095910370349884, -0.13243277370929718, 0.06056740880012512, -0.04802423343062401, -0.12318279594182968, -0.013157366774976254, -0.12076889723539352, -0.07183175534009933, -0.01982908323407173, -0.15032584965229034, -0.026652328670024872, 0.06820419430732727, -0.24668177962303162, 0.1818322390317917, -0.01959969662129879, -0.07208395004272461, -0.0680316612124443, -0.038368165493011475, 0.021410271525382996, 0.06388168036937714, 0.2293335199356079, -0.22541724145412445, 0.19133104383945465, 0.24343697726726532, -0.04034627974033356, 0.07534503191709518, 0.017645064741373062, 0.054646339267492294, -0.046512290835380554, 0.07076910138130188, -0.0960201621055603, -0.12610889971256256, -0.017934376373887062, -0.010262779891490936, 0.01885927841067314, 0.057148948311805725])
B = np.array([-0.08116298168897629, 0.1283080279827118, 0.024102725088596344, -0.03748808428645134, 0.06578215956687927, -0.07137967646121979, -0.10578329861164093, -0.0911930501461029, 0.19589228928089142, -0.09603863954544067, 0.2447616308927536, 0.07736924290657043, -0.17048686742782593, -0.1277867704629898, 0.06390697509050369, 0.12272421270608902, -0.19242052733898163, -0.08341517299413681, -0.11065894365310669, -0.09501136839389801, -0.010332206264138222, -0.008188878186047077, 0.08251037448644638, 0.04358505830168724, -0.1455313265323639, -0.3595622479915619, -0.07877802848815918, -0.18927346169948578, -0.0018955999985337257, -0.06280332803726196, -0.06073163449764252, 0.03181075677275658, -0.15109844505786896, -0.08682074397802353, 0.017340943217277527, -0.020879391580820084, 0.008258359506726265, 0.016738882288336754, 0.16803768277168274, 0.039162665605545044, -0.09613757580518723, 0.06231086328625679, 0.00924085732549429, 0.2418847680091858, 0.26051488518714905, 0.07355985790491104, 0.05239278823137283, -0.08052310347557068, 0.08884726464748383, -0.24261267483234406, 0.05618546903133392, 0.12175332009792328, 0.09056758135557175, 0.04266638681292534, 0.16591356694698334, -0.2005864679813385, 0.01018378883600235, 0.08819808065891266, -0.15550008416175842, 0.0815843716263771, 0.03018287755548954, -0.025435002520680428, -0.06714558601379395, 0.009693139232695103, 0.22243273258209229, 0.13470745086669922, -0.1363328993320465, 0.01635543815791607, 0.18212205171585083, -0.03392908349633217, 0.0398673489689827, 0.0043264636769890785, -0.15493592619895935, -0.2530894875526428, -0.23155181109905243, 0.0678660124540329, 0.31580865383148193, 0.21846994757652283, -0.20842058956623077, 0.012199334800243378, -0.12194785475730896, 0.059383176267147064, 0.0768171101808548, -0.012840969488024712, -0.11975857615470886, -0.11892750859260559, -0.03087366186082363, 0.04432998597621918, 0.09186872839927673, 0.0821407362818718, -0.018520792946219444, 0.1962793618440628, -0.0566205158829689, 0.026071354746818542, 0.007139421068131924, 0.02185123600065708, -0.11292634904384613, -0.044381096959114075, -0.18024618923664093, -0.007845945656299591, 0.010368190705776215, -0.07480168342590332, -0.0035089245066046715, 0.09972234815359116, -0.18773995339870453, 0.0474785715341568, 0.025760797783732414, -0.042169712483882904, 0.0014017894864082336, 0.1201503798365593, -0.05088714882731438, -0.02051539719104767, 0.0884844958782196, -0.2176845818758011, 0.25695914030075073, 0.23358485102653503, 0.019985560327768326, 0.17838242650032043, 0.029055196791887283, 0.04518195986747742, -0.044122979044914246, -0.043431997299194336, -0.15906637907028198, -0.07155231386423111, 0.02525237947702408, 0.02502967044711113, 0.04127159342169762, 0.011846683919429779])
C = np.array([-0.0762145072221756, 0.09951083362102509, 0.0012626983225345612, -0.05529194697737694, -0.006535547785460949, -0.012212716042995453, -0.07667708396911621, -0.07388101518154144, 0.18756520748138428, -0.07589773088693619, 0.2424328476190567, 0.06438330560922623, -0.22197730839252472, -0.13409815728664398, 0.046808283776044846, 0.14692817628383636, -0.1844339370727539, -0.051137253642082214, -0.1149090975522995, -0.1297808736562729, 0.040612753480672836, -0.002555673476308584, 0.10426937788724899, 0.026295233517885208, -0.13127824664115906, -0.35947439074516296, -0.048153407871723175, -0.17165206372737885, -0.0002263905480504036, -0.10254599899053574, -0.08338439464569092, 0.014203382655978203, -0.18179851770401, -0.13200539350509644, 0.03813670203089714, -0.012789442203938961, -0.0030085663311183453, -0.007307708729058504, 0.17558619379997253, 0.025768719613552094, -0.12877899408340454, 0.11051110923290253, 0.03616628795862198, 0.22539083659648895, 0.2838597595691681, 0.07483825087547302, -0.0036694444715976715, -0.09967216849327087, 0.11106447875499725, -0.22961333394050598, 0.06397823244333267, 0.12394970655441284, 0.06568531692028046, 0.037825535982847214, 0.09586739540100098, -0.18721607327461243, 0.01674063131213188, 0.10057111084461212, -0.15766742825508118, 0.008397659286856651, 0.039109550416469574, -0.06041106954216957, -0.046033550053834915, 0.031240269541740417, 0.2121172845363617, 0.103468157351017, -0.1224282756447792, -0.05559460073709488, 0.12153220176696777, -0.018480442464351654, 0.039875734597444534, 0.007489997893571854, -0.18950346112251282, -0.20904967188835144, -0.23732705414295197, 0.0895664244890213, 0.3778454661369324, 0.16606193780899048, -0.20442475378513336, 0.018602905794978142, -0.18367978930473328, 0.04945264756679535, 0.08889186382293701, 0.002995049115270376, -0.06196683272719383, -0.13028381764888763, -0.03548961132764816, 0.053789377212524414, 0.08386979252099991, 0.016627438366413116, -0.040179431438446045, 0.2289249151945114, -0.02149147540330887, 0.05046383664011955, 0.02314644865691662, 0.05424635857343674, -0.1627081036567688, -0.01140156015753746, -0.18031321465969086, -0.06785157322883606, 0.03336677327752113, -0.06467186659574509, 0.0466950424015522, 0.12832939624786377, -0.2377130389213562, 0.06774994730949402, 0.013810726813971996, -0.019034255295991898, 0.04477768391370773, 0.0660984218120575, -0.031004268676042557, -0.03275192156434059, 0.06632497161626816, -0.24120087921619415, 0.2647172510623932, 0.2477877289056778, 0.054315339773893356, 0.17328208684921265, 0.06950142979621887, 0.019016757607460022, -0.01211759727448225, -0.014044362120330334, -0.17701464891433716, -0.03347969055175781, 0.04914966598153114, 0.05660251900553703, 0.0644666999578476, 0.012375651858747005])
print("슝=3")
슝=3
- L2 Norm Distance
In [9]:
distances = np.linalg.norm([A, B] - C, axis=1, ord=2)
print("Distance between A and C: {}".format(distances[0]))
print("Distance between B and C: {}".format(distances[1]))
Distance between A and C: 0.8211549091846528 Distance between B and C: 0.34743558135053815
In [10]:
import numpy as np
x = np.array([1,2,3,4,5])
y = np.array([2,3,4,5,6])
print(np.linalg.norm(y-x, ord=1)) #L1 distance
print(np.linalg.norm(y-x, ord=2)) #L2 distance
5.0 2.23606797749979
In [11]:
def get_distance(name1, name2):
return np.linalg.norm(embedding_dict[name1]-embedding_dict[name2], ord=2)
get_distance('obama', 'trump')
Out[11]:
0.8885117374787042
5. 얼굴 임베딩 공간의 시각화¶
6. 닮은 꼴 찾기¶
- def get_gropped_face(image_file) : 이미지 파일에서 얼굴 영역을 가져오는 함수
- def get_face_embedding(face) : 얼굴영역으로부터 얼굴 임베딩 벡터를 구하는 함수
- def get_face_embedding_dict(dir_path) : 디렉토리 안에 있는 모든 이미지의 임베딩 딕셔너리를 구하는 함수
- def get_distance(name1, name2) : 두 이미지(사람 이름) 사이의 임베딩 벡터 거리를 구하는 함수
In [12]:
# name1과 name2의 거리를 비교하는 함수를 생성하되, name1은 미리 지정하고, name2는 호출시에 인자로 받도록 합니다.
def get_sort_key_func(name1):
def get_distance_from_name1(name2):
return get_distance(name1, name2)
return get_distance_from_name1
sort_key_func = get_sort_key_func('trump')
# 이렇게 생성된 함수 sort_key_func는 sort_key_func('obama') 라고 호출할 때 trump와 obama 사이의 임베딩 벡터 거리를 계산합니다.
In [13]:
sorted(embedding_dict.items(), key=lambda x:sort_key_func(x[0]))
Out[13]:
[('trump', array([-0.15962467, 0.20268655, 0.0323635 , 0.02439232, -0.06226439, 0.05140705, 0.07351795, -0.16823348, 0.06962204, -0.05557961, 0.17270109, -0.05094168, -0.35293093, -0.0316438 , 0.03792984, 0.17343847, -0.13260126, -0.15357377, -0.23523533, -0.08442692, -0.00134139, 0.03210667, -0.08926154, -0.02670781, -0.09581181, -0.25792354, -0.01056999, -0.11071672, 0.03133569, -0.07444921, 0.05670552, -0.02273796, -0.19461137, -0.04576054, 0.00947582, 0.01806056, -0.1502624 , -0.07787319, 0.17577608, 0.01933258, -0.19744575, -0.03930519, 0.07374467, 0.20196027, 0.1476755 , -0.0141539 , 0.0172476 , -0.11976205, 0.09462971, -0.24318144, -0.02755127, 0.12169892, 0.14837705, 0.17079785, 0.06952555, -0.15360466, 0.02005427, 0.08199155, -0.19544823, 0.10653654, 0.11468476, -0.21902837, -0.07677591, -0.06791042, 0.10587606, 0.05921567, -0.06115703, -0.11171092, 0.23917492, -0.15791436, -0.13834007, 0.01942121, 0.01826206, -0.1869376 , -0.32023543, 0.01407088, 0.34068239, 0.20081407, -0.19736893, -0.06809217, -0.0536031 , -0.03747801, 0.07641605, 0.09667511, -0.04759219, -0.09811257, -0.05056169, -0.01899303, 0.24124743, -0.04360487, 0.00636286, 0.21936756, 0.01126812, -0.04524586, -0.00227514, 0.02113587, -0.11754515, -0.05986457, -0.08348871, -0.07204333, -0.00065423, -0.14080839, 0.03825339, 0.08760153, -0.11946712, 0.18282008, 0.03533202, 0.01670191, -0.00815773, -0.00964593, -0.06726068, 0.01727787, 0.16389623, -0.16469438, 0.25836599, 0.20883362, -0.0511426 , 0.0673226 , 0.11310361, 0.08522274, -0.01515304, -0.03709226, -0.22167102, -0.18071674, 0.06958843, 0.02523582, -0.01741696, 0.03869874])), ('reagan', array([-0.07375357, 0.10346214, 0.05566559, 0.0695718 , -0.05440289, -0.01463646, -0.00649548, -0.09569547, 0.09449113, -0.04624915, 0.24829058, -0.09732288, -0.32321307, -0.02170691, -0.05216696, 0.08848224, -0.17542514, -0.00346639, -0.21609756, -0.05386934, 0.05907623, 0.05206383, -0.00552298, -0.03122731, -0.09512019, -0.28428546, -0.03761142, -0.10027184, 0.08096444, -0.08889769, -0.02716124, -0.03971988, -0.27534494, -0.16471916, -0.01999875, 0.0016112 , -0.04278624, -0.04995842, 0.10131402, -0.01418073, -0.18135472, 0.03161946, 0.04568903, 0.17763813, 0.22100508, 0.02493148, -0.03450565, -0.15785582, 0.11732896, -0.29776844, 0.00568237, 0.09540917, 0.17411588, 0.11876013, 0.13139085, -0.14378829, -0.02134267, 0.11733156, -0.13780983, 0.06715038, 0.05229622, -0.03175481, 0.03515494, -0.08317695, 0.04386129, 0.05435885, -0.02304641, -0.12853993, 0.17707913, -0.1982398 , -0.04517204, 0.13875599, 0.04342822, -0.15879723, -0.37596074, -0.05904536, 0.38085103, 0.13067873, -0.19391856, -0.06296147, -0.11909108, -0.07099086, 0.06326488, -0.01472369, -0.01706395, -0.02058249, -0.07531797, 0.04612498, 0.2340861 , -0.0592877 , 0.0136845 , 0.22591993, -0.01238802, -0.04330973, 0.06063112, 0.08095851, -0.14738627, -0.04548051, -0.11298802, -0.01335901, 0.0267882 , -0.13438657, 0.00160147, 0.05713233, -0.17619428, 0.14030355, -0.0064233 , -0.03354643, 0.02639963, -0.08354585, -0.03018388, 0.10711893, 0.20899144, -0.26083925, 0.24738196, 0.14037034, -0.07651532, 0.08729064, -0.01822417, 0.03990374, -0.09170216, -0.05556964, -0.18002766, -0.18664891, -0.0356429 , -0.04261817, -0.00853308, -0.01145224])), ('biden', array([-3.94153334e-02, 1.71419963e-01, 6.19103611e-02, 1.20813865e-03, -1.26029924e-01, 4.76813056e-02, -7.64570385e-02, -1.04280867e-01, 7.64882043e-02, -2.97834557e-02, 2.05395296e-01, -3.52288187e-02, -2.62895197e-01, 3.47554944e-02, 4.22611237e-02, 1.28316373e-01, -9.96532217e-02, -8.62354189e-02, -1.99026316e-01, -9.20077860e-02, -4.13053622e-03, -1.84574572e-03, 7.12383687e-02, -8.01764894e-04, -1.72330856e-01, -2.43130982e-01, -6.68652281e-02, -1.27878666e-01, -5.89288399e-02, -1.38829440e-01, 2.90382653e-02, -7.59892464e-02, -1.80036172e-01, -6.59002885e-02, -8.85275006e-03, -5.45807369e-03, -7.63356015e-02, -8.49744529e-02, 1.49971962e-01, 4.51882090e-03, -1.37575701e-01, 6.32099435e-02, 2.69454066e-03, 2.15510115e-01, 2.17975736e-01, 2.67775599e-02, 6.51229918e-02, -8.41554403e-02, 1.19427636e-01, -2.07337141e-01, 3.73023227e-02, 5.67626469e-02, 1.76523373e-01, 5.84511086e-02, 8.71435180e-02, -8.61171708e-02, 3.91412154e-02, 1.81429118e-01, -1.66551292e-01, 1.15131907e-01, 4.45637666e-02, -7.72319511e-02, 5.94520569e-03, -5.48956022e-02, 2.15550780e-01, 1.62481323e-01, -4.54511605e-02, -1.22476727e-01, 1.85941517e-01, -8.48648101e-02, -1.18062168e-01, 5.99945076e-02, -1.21605873e-01, -1.64801836e-01, -3.04567844e-01, -3.61244790e-02, 3.68216187e-01, 4.10148762e-02, -3.01204383e-01, -1.31272703e-01, -2.96852887e-02, 8.83649476e-03, 8.78813304e-03, 6.53453544e-02, -5.47639839e-02, -1.27447486e-01, -9.06510800e-02, 8.45456216e-03, 3.23339522e-01, -1.19672455e-01, -5.59653156e-02, 1.87589496e-01, 3.12539935e-02, -7.29634017e-02, 5.08752726e-02, 3.91780846e-02, -1.11397795e-01, -2.93459818e-02, -1.01636231e-01, -1.65463705e-02, -3.56077775e-02, -1.16203457e-01, -7.09438622e-02, 8.43822733e-02, -1.63478285e-01, 1.42183632e-01, -2.51595862e-02, -6.60387129e-02, -7.88670257e-02, 1.51667395e-04, -6.92283735e-02, -1.20748542e-02, 2.38132715e-01, -2.04149559e-01, 2.09254473e-01, 2.22607568e-01, -3.95926982e-02, 5.09544238e-02, -4.50846851e-02, 9.35904682e-02, -2.53209118e-02, 8.85853767e-02, -1.56866565e-01, -1.34990171e-01, 1.49547346e-02, -2.53867805e-02, -4.60821483e-03, 5.20500951e-02])), ('clinton', array([-0.04508969, 0.11096706, 0.04037839, -0.02596069, -0.13629276, 0.05832736, -0.00791329, -0.09079798, 0.07800291, -0.06751928, 0.07836544, -0.01847955, -0.20820636, -0.01413895, 0.03679249, 0.08727276, -0.09368371, -0.12994473, -0.13642883, -0.08290243, -0.05130973, 0.03095647, -0.07930112, 0.00835842, -0.1596638 , -0.25370046, -0.05857152, 0.00354732, 0.06525847, -0.05510001, 0.06141135, 0.07477431, -0.18673925, -0.01823538, -0.00579874, 0.0627984 , -0.11167405, -0.04451566, 0.10954212, 0.03735855, -0.18664123, 0.02195602, 0.00140925, 0.2867555 , 0.26321203, 0.05795337, 0.03520405, -0.04231023, 0.10563868, -0.25683585, 0.08387342, 0.10793852, 0.09012961, 0.11464255, -0.06066907, -0.10177629, 0.03965353, 0.15413532, -0.19503416, 0.06701506, 0.10005981, -0.19811633, -0.06047497, -0.00161708, 0.1978557 , 0.1070812 , -0.04738703, -0.16971821, 0.19489385, -0.20560056, -0.09854932, 0.05298131, -0.03782267, -0.10221337, -0.27675027, 0.07568289, 0.41247922, 0.1883022 , -0.15817063, -0.00522887, -0.08230484, 0.06390021, 0.11653241, 0.06747078, -0.07001634, -0.14668852, -0.05507295, 0.0080837 , 0.27537596, -0.01530384, -0.0812595 , 0.18434253, 0.09375615, -0.06444204, 0.03225123, -0.00673253, -0.05144547, 0.0044758 , -0.05725317, -0.09340777, 0.08545437, -0.05549682, 0.06186868, 0.14917053, -0.19328932, 0.37587884, 0.02196722, 0.06623412, 0.13318247, -0.02438419, -0.04212693, -0.01964648, 0.19658604, -0.23843254, 0.17401865, 0.14546792, 0.03816431, 0.1315241 , 0.07140416, 0.12920363, -0.00130752, -0.01432464, -0.17555533, -0.08830181, 0.08549964, -0.03470356, 0.08567261, 0.07909804])), ('bush', array([-0.02688614, 0.15357068, 0.00306777, -0.03736856, -0.14965256, 0.06046997, -0.0797798 , -0.04666145, 0.05967122, 0.05769293, 0.22493424, -0.07165433, -0.25231588, -0.01114981, -0.005116 , 0.14348006, -0.06599346, -0.08264632, -0.17776705, -0.07889958, -0.11334776, -0.0268334 , 0.02910631, 0.00105756, -0.07014772, -0.30125338, -0.02202353, -0.09172333, 0.09163113, -0.10745974, -0.06365715, 0.02872834, -0.27996549, -0.08004567, 0.05845983, 0.06112044, -0.13538527, -0.05882431, 0.22042616, 0.00287015, -0.10145169, 0.04976015, 0.09955782, 0.24114956, 0.21965373, 0.05165821, 0.02691336, -0.02191988, 0.14006718, -0.26064318, 0.08969024, 0.1297276 , 0.15132797, 0.09496952, 0.08723669, -0.16131578, 0.02279894, 0.11519404, -0.16123183, 0.03411197, -0.01044745, 0.0257275 , -0.12075561, -0.12607026, 0.28504804, 0.14975506, -0.05423341, -0.13247581, 0.19972019, -0.09743115, 0.00653269, 0.063984 , -0.09684457, -0.12205557, -0.2769821 , 0.08451798, 0.28124997, 0.06695339, -0.23141319, 0.00995516, 0.02213099, -0.06281434, -0.01617577, -0.02588859, -0.11061352, -0.02971569, -0.04043308, 0.00443799, 0.27804887, -0.12047102, 0.03416478, 0.16719851, 0.0124621 , -0.03100493, 0.04799554, 0.02550237, -0.06463958, -0.09388316, -0.19427463, -0.00120571, 0.04110978, -0.14921369, -0.0653673 , 0.07100558, -0.22958919, 0.07361019, 0.01149624, -0.06638756, -0.04884 , -0.0342384 , -0.0903028 , -0.04595109, 0.21033722, -0.26926798, 0.29246753, 0.15201515, -0.0249368 , 0.04324608, 0.05613966, 0.04076143, 0.02953195, 0.04104399, -0.09763061, -0.16920461, 0.06122242, -0.04344591, -0.08038266, 0.05807827])), ('obama', array([-0.08126248, 0.11014761, -0.01082448, -0.05268792, 0.01033717, -0.00813808, -0.07251769, -0.0922646 , 0.19304723, -0.09246384, 0.23908533, 0.06770287, -0.22123125, -0.14119367, 0.05562152, 0.13705511, -0.17924425, -0.07232306, -0.11183281, -0.11370818, 0.03956435, -0.01019115, 0.0942178 , 0.04493114, -0.12757549, -0.34449592, -0.05374938, -0.17703305, 0.00868226, -0.09721592, -0.09817187, 0.00278232, -0.17721367, -0.12789807, 0.03489833, -0.01991234, -0.00838933, -0.00132862, 0.18308581, 0.02447568, -0.1237656 , 0.09957044, 0.02323568, 0.22983313, 0.2838524 , 0.06655717, -0.00558912, -0.09833544, 0.10058986, -0.23476946, 0.06006292, 0.1341591 , 0.08373027, 0.03900504, 0.10194533, -0.19337648, 0.01717628, 0.08978969, -0.16005114, 0.01892098, 0.03082444, -0.06051281, -0.04526773, 0.04633342, 0.20678686, 0.10299795, -0.12437531, -0.0490516 , 0.12252682, -0.0280379 , 0.04286709, 0.01386448, -0.18673278, -0.22230086, -0.23382807, 0.07662997, 0.3739067 , 0.18993473, -0.20606737, 0.0244521 , -0.18487695, 0.04949443, 0.09670059, -0.00123947, -0.0688749 , -0.13414779, -0.04103697, 0.06179445, 0.07108597, 0.02471443, -0.04194992, 0.22575834, -0.02099216, 0.04838851, 0.02123774, 0.05604827, -0.14657559, -0.02243515, -0.17425998, -0.06527615, 0.02526723, -0.04892462, 0.05058879, 0.13397783, -0.23065181, 0.06054964, 0.02031171, -0.0191126 , 0.03631671, 0.06983903, -0.03496742, -0.03203756, 0.05493437, -0.24500111, 0.24993542, 0.24442896, 0.04081136, 0.16412377, 0.06019448, 0.0062465 , -0.00932551, -0.02752422, -0.17775527, -0.03611944, 0.04782868, 0.06031797, 0.06846569, 0.00587987]))]
In [14]:
def get_nearest_face(name, top=5):
sort_key_func = get_sort_key_func(name)
sorted_faces = sorted(embedding_dict.items(), key=lambda x:sort_key_func(x[0]))
for i in range(top+1):
if i == 0 : # 첫번째로 나오는 이름은 자기 자신일 것이므로 제외합시다.
continue
if sorted_faces[i]:
print('순위 {} : 이름({}), 거리({})'.format(i, sorted_faces[i][0], sort_key_func(sorted_faces[i][0])))
In [15]:
# obama와 가장 닮은 사람은 누굴까요?
get_nearest_face('obama')
순위 1 : 이름(biden), 거리(0.846720652777963) 순위 2 : 이름(bush), 거리(0.8628473227070342) 순위 3 : 이름(reagan), 거리(0.8692435806803928) 순위 4 : 이름(trump), 거리(0.8885117374787042) 순위 5 : 이름(clinton), 거리(0.9000994624487408)
7. 닮은 연예인 찾기¶
In [154]:
# 얼굴 추출용 메서드
import face_recognition
import os
def get_gropped_face(image_file):
image = face_recognition.load_image_file(image_file)
face_locations = face_recognition.face_locations(image)
a, b, c, d = face_locations[0]
cropped_face = image[a:c,d:b,:]
return cropped_face
In [155]:
image_path = os.getenv('HOME')+'/aiffel/face_embedding/images/msb2.jpg'
cropped_face = get_gropped_face(image_path)
plt.imshow(cropped_face)
Out[155]:
<matplotlib.image.AxesImage at 0x7f9e91cf9d90>
In [156]:
import os
dir_path = os.getenv('HOME')+'/aiffel/face_embedding/images'
file_list = os.listdir(dir_path)
print ("file_list: {}".format(file_list))
file_list: ['a14.jpeg', 'a78.jpeg', 'reagan.jpg', 'a60.png', 'a16.jpeg', 'a29.jpeg', 'a15.jpeg', 'a9.jpeg', 'bush.jpeg', 'a30.jpeg', 'a64.jpeg', 'msb1.jpg', 'a47.jpeg', 'a12.jpeg', 'a3.jpeg', 'biden.jpg', 'a4.jpeg', 'clinton.jpeg', 'trump.jpg', 'obama.jpg', 'a71.jpeg', 'a31.jpeg', 'a65.jpeg', 'a73.jpeg', 'a58.jpeg', 'a21.jpeg', 'msb2.jpg', 'a50.jpeg', 'a61.jpeg']
In [157]:
image_file = os.path.join(dir_path, 'msb1.jpg')
face = get_gropped_face(image_file) # 얼굴 영역을 구하는 함수(이전 스텝에서 구현)
# 얼굴 영역을 가지고 얼굴 임베딩 벡터를 구하는 함수
def get_face_embedding(face):
return face_recognition.face_encodings(face)
embedding = get_face_embedding(face)
embedding
Out[157]:
[array([-0.13136627, 0.15618166, -0.02692805, -0.01400604, -0.10619154, -0.04361857, -0.01505203, -0.08140046, 0.13226353, -0.10607781, 0.17847739, -0.06145298, -0.26290143, -0.05164105, -0.06066348, 0.18100506, -0.22103375, -0.17492832, -0.0229451 , 0.02995389, 0.10931139, 0.05232136, -0.01161923, 0.05676125, -0.10659552, -0.33555496, -0.04281763, -0.03746015, 0.01862585, -0.05229235, 0.01968587, 0.03673005, -0.16946079, -0.03070766, 0.02470896, 0.07283298, 0.01577045, -0.00998005, 0.22429988, -0.02913842, -0.32884848, 0.04133387, 0.08441103, 0.31741655, 0.14846553, 0.01849345, -0.00202652, -0.1723887 , 0.09715892, -0.18747669, 0.01814087, 0.17067078, 0.06004209, 0.01798143, -0.01206748, -0.16357131, 0.00044232, 0.10456246, -0.13244455, -0.00703787, 0.10106587, -0.03167924, 0.05358784, -0.08293861, 0.20975965, -0.04269535, -0.13269699, -0.15654802, 0.11821878, -0.18320426, -0.08715839, 0.12202714, -0.09723086, -0.19637205, -0.36284634, -0.01229202, 0.42556977, 0.09010722, -0.11870622, 0.09619489, -0.03434257, -0.02654167, 0.15380709, 0.18193543, -0.03852752, 0.01843868, -0.11245311, 0.04946603, 0.26274166, -0.02653348, -0.07348321, 0.17249489, 0.04826339, 0.06694703, 0.02252911, 0.07928812, -0.05279647, 0.02296429, -0.13731916, 0.03042262, 0.01684891, -0.05987137, -0.02264472, 0.15932682, -0.15790477, 0.12078388, 0.04076353, 0.03515633, 0.00421338, 0.07437196, -0.09200966, -0.04942237, 0.11320905, -0.24152987, 0.21343534, 0.16653416, 0.03926207, 0.10708857, 0.1276574 , 0.05527842, -0.02422268, -0.02695185, -0.22733197, -0.04285222, 0.10226104, -0.05072335, 0.1622963 , 0.01998287])]
In [158]:
# images 디렉토리 안에 있는 모든 이미지 파일의 임베딩을 구해서 dict 구조에 담아 리턴하는 함수
def get_face_embedding_dict(dir_path):
file_list = os.listdir(dir_path)
embedding_dict = {}
for file in file_list:
img_path = os.path.join(dir_path, file)
face = get_gropped_face(img_path)
embedding = get_face_embedding(face)
if len(embedding) > 0: # 얼굴영역 face가 제대로 detect되지 않으면 len(embedding)==0인 경우가 발생하므로
# os.path.splitext(file)[0]에는 이미지파일명에서 확장자를 제거한 이름이 담깁니다.
embedding_dict[os.path.splitext(file)[0]] = embedding[0]
return embedding_dict
In [159]:
embedding_dict = get_face_embedding_dict(dir_path)
embedding_dict['msb2']
Out[159]:
array([-0.1234505 , 0.05516115, -0.06562391, -0.03784493, -0.07705016, -0.0719053 , -0.07225392, -0.10601629, 0.12658034, -0.08016805, 0.17683956, -0.06013265, -0.20853733, -0.0748226 , -0.07167539, 0.15847582, -0.20934266, -0.12170348, -0.04367823, 0.0337344 , 0.12495674, 0.05176136, -0.00041227, 0.06343375, -0.17253153, -0.32206312, -0.03755248, -0.09046519, -0.01335652, -0.00637895, -0.02607523, 0.03857142, -0.20072016, -0.03552698, 0.07408307, 0.12704988, 0.00236222, -0.00666057, 0.19593558, 0.00886324, -0.28749016, 0.03107352, 0.04332944, 0.27991909, 0.20944385, 0.03042535, 0.02104956, -0.16909346, 0.14805634, -0.1872862 , 0.03230308, 0.15753689, 0.06612798, 0.02577797, 0.00845574, -0.12776092, 0.01408827, 0.15630817, -0.13508147, 0.00622187, 0.12048115, -0.02775652, 0.03127323, -0.11172935, 0.23382899, -0.01552319, -0.17660998, -0.13537705, 0.11272801, -0.18223399, -0.08272883, 0.07603208, -0.12036071, -0.22541645, -0.36187512, -0.01765027, 0.38334218, 0.11772528, -0.18007204, 0.06607848, -0.03741917, -0.00067432, 0.17818245, 0.15878886, 0.02235381, 0.03519096, -0.07991894, -0.00455463, 0.29835758, -0.0327536 , -0.02594212, 0.20267902, -0.0027496 , 0.05036955, 0.00907635, 0.02442246, -0.08316794, 0.01295763, -0.10689633, 0.03508601, -0.01056929, -0.03902517, 0.00904335, 0.14546166, -0.13463628, 0.14021224, -0.00561361, 0.05058458, 0.00974113, -0.00177958, -0.10634066, -0.06062442, 0.12011519, -0.21698478, 0.22832607, 0.1380612 , 0.1013038 , 0.11054899, 0.11227035, 0.04911305, -0.03656888, 0.03757948, -0.26045236, -0.02913027, 0.09076686, -0.0600445 , 0.15124942, -0.01307622])
In [162]:
def get_distance(name1, name2):
return np.linalg.norm(embedding_dict[name1]-embedding_dict[name2], ord=2)
get_distance('msb1', 'msb2')
Out[162]:
0.35813132984422946
In [163]:
def get_nearest_face(name, top=5):
sort_key_func = get_sort_key_func(name)
sorted_faces = sorted(embedding_dict.items(), key=lambda x:sort_key_func(x[0]))
for i in range(top+1):
if i == 0 : # 첫번째로 나오는 이름은 자기 자신일 것이므로 제외합시다.
continue
if sorted_faces[i]:
print('순위 {} : 이름({}), 거리({})'.format(i, sorted_faces[i][0], sort_key_func(sorted_faces[i][0])))
In [164]:
get_nearest_face('msb1')
순위 1 : 이름(msb2), 거리(0.35813132984422946) 순위 2 : 이름(a12), 거리(0.43921861767610937) 순위 3 : 이름(a71), 거리(0.49650857701682277) 순위 4 : 이름(a58), 거리(0.5004786528024681) 순위 5 : 이름(a3), 거리(0.5182933570502293)
정리¶
- 개념을 이해했지만 얼굴이 인식되지 않는 사진을 try catch로 예외처리해줘야한다는 것은 알겠는데 정확히 어느부분을 어떻게 처리해야하는지 파이썬을 이해 못함(얼굴 인식이 될만한 사진들만 직접 골라서 추림...)
- 임베딩거리 0.5 미만을 찾긴 했으나 사진 추리는 과정이 모자람.
- PIL의 Image.fromarray를 통해서 PIL Image로 변환한 뒤에 저장하는 방법인데 아직 이해 못함.. from PIL import Image face = get_gropped_face(image_path) pillow_image = Image.fromarray(face) pillow_image.save(path_to_save)
- tkinter나 flask를 활용해서 닮은꼴을 찾을 이미지를 업로드한 후 그 이미지와 닮은 얼굴을 찾는 형태로 구현해 보는 것도 해볼 것.
'AIFFEL' 카테고리의 다른 글
Explolation9 캐글 따라해보기 - 주택가격 예측 (0) | 2021.02.02 |
---|---|
Explolation 8 영화 추천 시스템 만들기 (0) | 2021.01.29 |
Explolation 6 작사가 만들기 (0) | 2021.01.21 |
Exploration5 오디오 음성 데이터 분류 (0) | 2021.01.19 |
Exploration4 영화 리뷰 감성 분류 (0) | 2021.01.14 |