[PYTHON] Implementieren Sie eine ähnliche Gesichtssuche in einem halben Tag

Als Experiment für unseren eigenen sozialen Dienst haben wir einen einfachen Prototyp der Gesichtserkennungsfunktion erstellt. Es ist sehr einfach und fast durch Aufrufen der Python-Bibliothek erledigt, sodass dieser Artikel technisch überhaupt nicht interessant ist (lacht). Ich dachte nicht, dass es so einfach sein würde, oder ich konnte solche Informationen nicht durch Suchen finden, also würde ich sie gerne teilen.

Vorausgesetztes Wissen

Ich brauche nichts Ich bin ein Amateur in Python und maschinellem Lernen.

Bibliothek

https://github.com/ageitgey/face_recognition

Verwenden Sie diese Bibliothek. Es ist wie ein Wrapper für dlib, eine Bibliothek, die angeblich stark in der Gesichtserkennung ist.

Wie es funktioniert

Die obige Bibliothek verfügt über eine Methode namens face_encodings. Wenn Sie die Bilddatei an diese Methode übergeben, wird das Gesicht [Orientierungspunkt](https://www.google.co.jp/search?biw=2339&bih=1240&tbm=isch&sa=1&q=face+landmarks&oq=face+landmarks&gs_l=psy- ab.3..0i19k1j0i7i30i19k1l7.10726.11076.0.11164.4.4.0.0.0.0.142.354.1j2.3.0 .... 0 ... 1.1.64.psy-ab..2.2.256 ... 0i7i30k1.L9q0iFem60Q #imgrc = JXb98Axur796VM :) Gibt einen Koordinatenvektor zurück.

Beispiel:

[-0.14351621270179749, 0.057226795703172684, 0.07066182047128677, -0.13657408952713013, -0.0695628970861435, -0.09160482883453369, -0.011631922796368599, -0.14444005489349365, 0.1372034251689911, -0.12074219435453415, 0.2784915566444397, -0.1435723453760147, -0.301411509513855, -0.006434443406760693, -0.06611043959856033, 0.21539726853370667, -0.1636665165424347, -0.13245481252670288, -0.08063990622758865, 0.04853415489196777, 0.09177280962467194, -0.01833999715745449, 0.00841446127742529, 0.12095664441585541, -0.08568297326564789, -0.37953001260757446, -0.13193728029727936, -0.03719043731689453, -0.0870690569281578, -0.04294124245643616, -0.038571640849113464, 0.05095953121781349, -0.2148473709821701, -0.041665997356176376, 0.014024296775460243, 0.07775825262069702, -0.034873172640800476, -0.15043900907039642, 0.17863482236862183, -0.030670292675495148, -0.2826652228832245, 0.02874363772571087, 0.09433827549219131, 0.20609621703624725, 0.1781337857246399, 0.005972636863589287, -0.021562352776527405, -0.16687169671058655, 0.07589639723300934, -0.20823828876018524, 0.027126934379339218, 0.10467753559350967, 0.06701159477233887, 0.07915465533733368, -0.024046622216701508, -0.1669970601797104, 0.07604529708623886, 0.1269170194864273, -0.21936824917793274, -0.06592322885990143, 0.06071619316935539, -0.14255106449127197, -0.047067590057849884, -0.08292384445667267, 0.2115967869758606, 0.18284666538238525, -0.15493471920490265, -0.14141127467155457, 0.15566584467887878, -0.1567707657814026, -0.005966860800981522, 0.02694620192050934, -0.14431986212730408, -0.19422967731952667, -0.27188384532928467, 0.003987520933151245, 0.2886632978916168, 0.051324617117643356, -0.24798262119293213, 0.028046492487192154, -0.03672055900096893, 0.048082903027534485, 0.10906309634447098, 0.16191940009593964, -0.008259378373622894, 0.005847998894751072, -0.11125662177801132, 0.006064308807253838, 0.1905171126127243, -0.07413583993911743, 0.02043292298913002, 0.290202260017395, 0.00569811649620533, -0.00016449671238660812, 0.11121324449777603, 0.10905371606349945, -0.09846137464046478, 0.005683856084942818, -0.15451037883758545, 0.05895839259028435, 0.04510065168142319, -0.03569173067808151, -0.06883768737316132, 0.08693848550319672, -0.16857297718524933, 0.1154068261384964, 0.007511516101658344, -0.01983277127146721, 0.02589372731745243, -0.09050130844116211, -0.020625963807106018, -0.11194785684347153, 0.08375582844018936, -0.22212722897529602, 0.17791825532913208, 0.13751709461212158, 0.0053409687243402, 0.1599988043308258, 0.060513101518154144, 0.10321187227964401, -0.030407054349780083, -0.03938911110162735, -0.22134312987327576, 0.0003300569951534271, 0.15529313683509827, 0.004012138117104769, 0.06936727464199066, -0.019267655909061432]

Führen Sie diese Konvertierung für alle Bilder im Voraus durch. Ob ein Foto einem Foto ähnlich ist, wird einfach durch die Nähe dieses Vektors bestimmt. Es ist einfach!

Die Vektorentfernung verwendet nur die euklidische Entfernung. Ich habe den Suchteil in Ruby erstellt, daher habe ich die Entfernungsberechnung entsprechend implementiert. Wenn Sie jedoch auch in Python suchen, gibt es eine Methode namens face_distance, sodass Sie diese auch verwenden können. Sehen Sie sich den Code in [Beispiel] kurz an (https://github.com/ageitgey/face_recognition/blob/master/examples/face_distance.py).

Installation

Ich werde erklären, wie es unter Ubuntu geht.

Zuerst brauchst du Python und Pip.

apt install python3-pip

Sie benötigen Boost und Cmake, um Dlib zu erstellen.

apt install cmake libboost-dev libboost-python-dev

Installieren Sie am Ende die Python-Bibliothek.

pip3 install face_recognition

Code

Codierung

Lassen Sie uns zunächst das Bild in einen Vektor codieren. Schreiben Sie das folgende dreizeilige Skript

import face_recognition
import json
import sys
 
image = face_recognition.load_image_file(sys.argv[1])
face_encoding = face_recognition.face_encodings(image)[0]
print(json.dumps(face_encoding.tolist()))

Ich werde es versuchen.

$ python3 recognize.py face.jpeg
[-0.14351621270179749, 0.057226795703172684, 0.07066182047128677, -0.13657408952713013, -0.0695628970861435, -0.09160482883453369, -0.011631922796368599, -0.14444005489349365, 0.1372034251689911, -0.12074219435453415, 0.2784915566444397, -0.1435723453760147, -0.301411509513855, -0.006434443406760693, -0.06611043959856033, 0.21539726853370667, -0.1636665165424347, -0.13245481252670288, -0.08063990622758865, 0.04853415489196777, 0.09177280962467194, -0.01833999715745449, 0.00841446127742529, 0.12095664441585541, -0.08568297326564789, -0.37953001260757446, -0.13193728029727936, -0.03719043731689453, -0.0870690569281578, -0.04294124245643616, -0.038571640849113464, 0.05095953121781349, -0.2148473709821701, -0.041665997356176376, 0.014024296775460243, 0.07775825262069702, -0.034873172640800476, -0.15043900907039642, 0.17863482236862183, -0.030670292675495148, -0.2826652228832245, 0.02874363772571087, 0.09433827549219131, 0.20609621703624725, 0.1781337857246399, 0.005972636863589287, -0.021562352776527405, -0.16687169671058655, 0.07589639723300934, -0.20823828876018524, 0.027126934379339218, 0.10467753559350967, 0.06701159477233887, 0.07915465533733368, -0.024046622216701508, -0.1669970601797104, 0.07604529708623886, 0.1269170194864273, -0.21936824917793274, -0.06592322885990143, 0.06071619316935539, -0.14255106449127197, -0.047067590057849884, -0.08292384445667267, 0.2115967869758606, 0.18284666538238525, -0.15493471920490265, -0.14141127467155457, 0.15566584467887878, -0.1567707657814026, -0.005966860800981522, 0.02694620192050934, -0.14431986212730408, -0.19422967731952667, -0.27188384532928467, 0.003987520933151245, 0.2886632978916168, 0.051324617117643356, -0.24798262119293213, 0.028046492487192154, -0.03672055900096893, 0.048082903027534485, 0.10906309634447098, 0.16191940009593964, -0.008259378373622894, 0.005847998894751072, -0.11125662177801132, 0.006064308807253838, 0.1905171126127243, -0.07413583993911743, 0.02043292298913002, 0.290202260017395, 0.00569811649620533, -0.00016449671238660812, 0.11121324449777603, 0.10905371606349945, -0.09846137464046478, 0.005683856084942818, -0.15451037883758545, 0.05895839259028435, 0.04510065168142319, -0.03569173067808151, -0.06883768737316132, 0.08693848550319672, -0.16857297718524933, 0.1154068261384964, 0.007511516101658344, -0.01983277127146721, 0.02589372731745243, -0.09050130844116211, -0.020625963807106018, -0.11194785684347153, 0.08375582844018936, -0.22212722897529602, 0.17791825532913208, 0.13751709461212158, 0.0053409687243402, 0.1599988043308258, 0.060513101518154144, 0.10321187227964401, -0.030407054349780083, -0.03938911110162735, -0.22134312987327576, 0.0003300569951534271, 0.15529313683509827, 0.004012138117104769, 0.06936727464199066, -0.019267655909061432]

Oh einfach! Tun Sie dies für alle Bilder und speichern Sie sie in einer Datenbank.

Suche

Ich bin nicht an Python gewöhnt oder der Produktcode basiert auf Ruby, daher habe ich den Suchteil in Ruby erstellt. Das heißt, im Wesentlichen tun Sie nur Folgendes:

Wenn Sie das Bild suchen, nach dem Sie suchen möchten, konvertieren Sie es zuerst mit dem obigen Python-Programm in einen Vektor und übergeben Sie es an die nächste Methode. In der vereinfachten Version hat all_vectors alle Vektoren vorab in den Speicher geladen.

def search(v)
  @all_vectors.min_by |u|
    euclidean_distance(u,v)
  end
end

Ich denke, es ist einfach anzupassen, wie zum Beispiel die Top 10 Plätze zurückzugeben.

Ergebnis

Es wäre schön, wenn ich das resultierende Foto einfügen könnte, aber ich kann es nicht zeigen, da es nur ein Foto des Gesichts des Dienstnutzers gibt.

Mein persönlicher Eindruck ist, dass es für eine Funktion, die in einem halben Tag erstellt wurde, gut gemacht ist. Ist es die gleiche Person? Manchmal werden ähnliche Gesichter auf der Ebene vorgeschlagen, von der Sie glauben, dass sie es sind, und manchmal werden Gesichter vorgeschlagen, die nicht sehr ähnlich sind. Ich habe ungefähr 30.000 Bilder verwendet, aber in ungefähr 70% der Fälle habe ich Bilder vorgeschlagen, die ich ähnlich fühlen könnte. Diese Art von Funktion ist immer noch selten, und ich denke, sie entspricht der attraktiven Qualität des Kano-Modells. Daher müssen nicht alle Ergebnisse ähnlich sein. In diesem Sinne war ich der Meinung, dass dies ein Niveau ist, das mit unserem eigenen Service in die Praxis umgesetzt werden kann.

Es mag natürlich sein, aber Bilder verschiedener Geschlechter wurden selten vorgeschlagen.

Es scheint, dass die Genauigkeit durch Erhöhen der Anzahl der Bilder erhöht wird.

Wenn es funktioniert

Ich denke, es funktioniert gut für charakteristische Gesichter wie ein sehr gut organisiertes Gesicht, abgerundete Gesichtskonturen und große Augen.

Wenn es nicht funktioniert

Zunächst wurde in den folgenden Fällen das Gesicht überhaupt nicht erkannt.

Fotos mit kleinen Gesichtern scheinen ziemlich angemessen codiert zu sein und verursachen Rauschen. Entfernen Sie sie daher besser. Sie können solche Bilder leicht identifizieren. (Verwenden Sie eine Methode namens face_locations)

Grenzen

Wie eingangs erwähnt, ist diese Bibliothek eine Funktion, die nur die Informationen von Gesichtspunkten als Merkmal extrahiert und vergleicht. Dies bedeutet, dass Sie nur Informationen wie:

Andererseits werden die folgenden Informationen nicht verwendet.

Wenn Sie eine ähnliche Suche mit solch detaillierten Informationen durchführen möchten, müssen Sie meines Erachtens Deep Learning verwenden.

Beschleunigen

Im obigen Beispiel haben wir eine lineare Suche durchgeführt, bei der einfach alle Bilder verglichen werden. Dies wird jedoch unbrauchbar, wenn die Anzahl der Bilder etwa 10.000 erreicht.

https://ekzhu.github.io/datasketch/lshforest.html

Mit einer solchen probabilistischen Approximationsbibliothek können Sie mit hoher Geschwindigkeit suchen.

Recommended Posts

Implementieren Sie eine ähnliche Gesichtssuche in einem halben Tag
Schreiben Sie eine Dichotomie in Python
Implementieren Sie einen Datumssetzer in Tkinter
Schreiben Sie eine Suche mit Tiefenpriorität in Python
Implementieren Sie einen benutzerdefinierten View Decorator mit Pyramid
Implementieren Sie ein benutzerdefiniertes Benutzermodell in Django
Starten Sie in 5 Minuten einen einfachen passwortgeschützten Suchdienst
So implementieren Sie eine Verlaufsauswahl in Houdini
Heppoko entwickelt den Webdienst in einer Woche # 2 Domain Search
Ich möchte Timeout einfach in Python implementieren
Ich habe versucht, einen Pseudo-Pachislot in Python zu implementieren
Implementieren Sie die Suche nach Tiefenpriorität (DFS) und die Suche nach Breitenpriorität (BFS) in Python