Преглед на файлове

update face recognition method

kevin преди 2 години
родител
ревизия
e9bff3cf3e
променени са 4 файла, в които са добавени 235 реда и са изтрити 30 реда
  1. 82 8
      face_recognition_svm.py
  2. 61 17
      fr_flask.py
  3. 38 5
      verify_face.py
  4. 54 0
      verify_face_2.py

+ 82 - 8
face_recognition_svm.py

@@ -5,6 +5,7 @@ import os
 import concurrent.futures
 import numpy as np
 import time
+import re
 
 # Training the SVC classifier
 
@@ -14,17 +15,81 @@ names = []
 tuples = []
 train_list = []
 lock = None
+model_name = 'saved_model_2.pkl'
+known_people_folder = os.path.join('application_data', 'verification_images')
+
+dummy_data = [
+    {
+        "name": "Bayu",
+        "address": "299 St Louis Road Oak Forest, IL 60452",
+        "nik": "1000076456784631"
+    },
+    {
+        "name": "Dio",
+        "address": "22 Whitemarsh St. Mansfield, MA 02048",
+        "nik": "1000024792887549"
+    },
+    {
+        "name": "Hadi",
+        "address": "643 Honey Creek Dr. Milledgeville, GA 31061",
+        "nik": "1000038502830420"
+    },
+    {
+        "name": "Kevin",
+        "address": "881 Cooper Ave. Hummelstown, PA 17036",
+        "nik": "1000045356476664"
+    },
+    {
+        "name": "Matrix",
+        "address": "580 Glenwood Dr. Garner, NC 27529",
+        "nik": "1000023452134598"
+    },
+    {
+        "name": "Surya",
+        "address": "909 South St Paul Street Hopewell, VA 23860",
+        "nik": "1000075656784734"
+    },
+]
+
+def scan_known_people(known_people_folder):
+    known_names = []
+    known_face_encodings = []
+
+    for file in image_files_in_folder(known_people_folder):
+        img = face_recognition.load_image_file(file)
+        encodings = face_recognition.face_encodings(img)
+
+        if len(encodings) > 1:
+            print("WARNING: More than one face found in {}. Only considering the first face.".format(file))
+
+        if len(encodings) == 0:
+            print("WARNING: No faces found in {}. Ignoring file.".format(file))
+        else:
+            known_face_encodings.append(encodings[0])
+
+    return known_face_encodings
+
+
+def image_files_in_folder(folder):
+    img_list = [os.path.join(folder, f) for f in os.listdir(folder) if
+                re.match(r'.*\.(jpg|jpeg|png|webp)', f, flags=re.I)]
+    img_list.sort()
+    return img_list
+
+
+face_encodings = scan_known_people(known_people_folder)
 
 is_train = False
 
 if not is_train:
     try:
-        clf = joblib.load('saved_model.pkl')
+        clf = joblib.load(model_name)
     except:
         clf = None
     if clf is None:
         is_train = True
 
+
 def train_image(image, person):
     face = face_recognition.load_image_file(image)
     face_bounding_boxes = face_recognition.face_locations(face)
@@ -37,10 +102,12 @@ def train_image(image, person):
     else:
         print(image + " was skipped and can't be used for training")
 
+
 if is_train:
     # Training directory
     train_str = os.path.join('data', 'train')
     train_dir = os.listdir(os.path.join('data', 'train'))
+    train_dir.sort()
 
     # Loop through each person in the training directory
     with concurrent.futures.ThreadPoolExecutor() as executor:
@@ -61,10 +128,10 @@ if is_train:
 
     clf = svm.SVC(gamma='scale', probability=True)
     clf.fit(encodings, names)
-    joblib.dump(clf, 'saved_model.pkl')
+    joblib.dump(clf, model_name)
 
 # Load the test image with unknown faces into a numpy array
-test_image = face_recognition.load_image_file(os.path.join('application_data', 'input_image', 'input_image2.jpg'))
+test_image = face_recognition.load_image_file(os.path.join('application_data', 'input_image', 'input_image.jpg'))
 
 # Find all the faces in the test image using the default HOG-based model
 face_locations = face_recognition.face_locations(test_image)
@@ -76,12 +143,19 @@ print("Found:")
 for i in range(no):
     test_image_enc = face_recognition.face_encodings(test_image)[i]
     start_time = time.perf_counter_ns()
-    proba = clf.predict_proba([test_image_enc])
+    proba_list = clf.predict_proba([test_image_enc])
+    dist = face_recognition.face_distance(face_encodings, test_image_enc)
+    total = np.subtract(proba_list, dist)
     end_time = time.perf_counter_ns()
     process_time = end_time - start_time
     classes = clf.classes_
     print(classes)
-    i = np.argmax(proba)
-    proba = list(*proba)
-    name = classes[i]
-    print(name, "{:.2f}".format(proba[i]), proba, process_time)
+    print(total)
+    i = np.argmax(total)
+    proba = list(*proba_list)
+    name = dummy_data[i]["name"]
+    print(name, "{:.2f}".format(proba[i]))
+    print(proba)
+    print(list(dist))
+    print(list(*total))
+    print(process_time)

+ 61 - 17
fr_flask.py

@@ -5,11 +5,14 @@ import base64
 from io import BytesIO
 import joblib
 import numpy as np
+import re
+import os
+import time
 
 ImageFile.SAFEBLOCK = 2048 * 2048
 
 app = Flask(__name__)
-model_file_name = "saved_model.pkl"
+model_file_name = "saved_model_2.pkl"
 clf = None
 classes = None
 dummy_data = [
@@ -45,6 +48,35 @@ dummy_data = [
     },
 ]
 ssl = None
+known_people_folder = "application_data/verification_images"
+face_encodings = []
+total_threshold = 0.2
+
+
+def scan_known_people(known_people_folder):
+    known_names = []
+    known_face_encodings = []
+
+    for file in image_files_in_folder(known_people_folder):
+        img = face_recognition.load_image_file(file)
+        encodings = face_recognition.face_encodings(img)
+
+        if len(encodings) > 1:
+            print("WARNING: More than one face found in {}. Only considering the first face.".format(file))
+
+        if len(encodings) == 0:
+            print("WARNING: No faces found in {}. Ignoring file.".format(file))
+        else:
+            known_face_encodings.append(encodings[0])
+
+    return known_face_encodings
+
+
+def image_files_in_folder(folder):
+    img_list = [os.path.join(folder, f) for f in os.listdir(folder) if
+                re.match(r'.*\.(jpg|jpeg|png|webp)', f, flags=re.I)]
+    img_list.sort()
+    return img_list
 
 
 @app.route('/predict', methods=['POST'])
@@ -63,22 +95,32 @@ def predict():
     test_image = face_recognition.load_image_file(im_file)
     face_locations = face_recognition.face_locations(test_image)
     no = len(face_locations)
-    for i in range(no):
-        test_image_enc = face_recognition.face_encodings(test_image)[i]
-        proba_list = clf.predict_proba([test_image_enc])
-        i = np.argmax(proba_list)
-        proba = list(*proba_list)[i]
-        name = dummy_data[i]["name"]
-        address = dummy_data[i]["address"]
-        nik = dummy_data[i]["nik"]
-        js = {
-            "id": str(i),
-            "name": name,
-            "address": address,
-            "nik": nik,
-            "proba": proba
-        }
-        result.append(js)
+    if no > 0:
+        for i in range(no):
+            start_time = time.perf_counter()
+            test_image_enc = face_recognition.face_encodings(test_image)[i]
+            proba_list = clf.predict_proba([test_image_enc])
+            dist = face_recognition.face_distance(face_encodings, test_image_enc)
+            total = np.subtract(proba_list, dist)
+            i = np.argmax(total)
+            proba = list(*proba_list)[i]
+            name = dummy_data[i]["name"]
+            address = dummy_data[i]["address"]
+            nik = dummy_data[i]["nik"]
+            js = {
+                "id": str(i),
+                "name": name,
+                "address": address,
+                "nik": nik,
+                "proba": proba
+            }
+            if total[0][i] > total_threshold:
+                result.append(js)
+            end_time = time.perf_counter()
+            process_time = end_time - start_time
+            print(total[0])
+            print("Process time:", process_time, "s")
+    print(result)
     return jsonify(result)
 
 
@@ -87,6 +129,8 @@ if __name__ == '__main__':
         clf = joblib.load(model_file_name)
         classes = clf.classes_
         print('model loaded')
+        face_encodings = scan_known_people(known_people_folder)
+        print('known faces scanned')
 
     except FileNotFoundError as e:
         print('No model here')

+ 38 - 5
verify_face.py

@@ -5,7 +5,7 @@ import joblib
 import time
 
 # This is a super simple (but slow) example of running face recognition on live video from your webcam.
-# There's a second example that's a little more complicated but runs faster.
+# There's a second example that's a little more complicatedq but runs faster.
 
 # PLEASE NOTE: This example requires OpenCV (the `cv2` library) to be installed only to read from your webcam.
 # OpenCV is *not* required to use the face_recognition library. It's only required if you want to run this
@@ -14,10 +14,43 @@ import time
 # Get a reference to webcam #0 (the default one)
 video_capture = cv2.VideoCapture(0)
 
-clf = joblib.load('saved_model.pkl')
+clf = joblib.load('saved_model_2.pkl')
 classes = clf.classes_
 
-threshold = 0.65
+threshold = 0.9
+
+dummy_data = [
+    {
+        "name": "Bayu",
+        "address": "299 St Louis Road Oak Forest, IL 60452",
+        "nik": "1000076456784631"
+    },
+    {
+        "name": "Dio",
+        "address": "22 Whitemarsh St. Mansfield, MA 02048",
+        "nik": "1000024792887549"
+    },
+    {
+        "name": "Hadi",
+        "address": "643 Honey Creek Dr. Milledgeville, GA 31061",
+        "nik": "1000038502830420"
+    },
+    {
+        "name": "Kevin",
+        "address": "881 Cooper Ave. Hummelstown, PA 17036",
+        "nik": "1000045356476664"
+    },
+    {
+        "name": "Matrix",
+        "address": "580 Glenwood Dr. Garner, NC 27529",
+        "nik": "1000023452134598"
+    },
+    {
+        "name": "Surya",
+        "address": "909 South St Paul Street Hopewell, VA 23860",
+        "nik": "1000075656784734"
+    },
+]
 
 while True:
     # Grab a single frame of video
@@ -40,7 +73,7 @@ while True:
         process_time = end_time - start_time
         i = np.argmax(proba_list)
         proba = list(*proba_list)[i]
-        name = classes[i]
+        name = dummy_data[i]["name"]
         print(name, "{:.2f}".format(proba), proba_list, process_time)
 
         # Draw a box around the face
@@ -48,7 +81,7 @@ while True:
 
         # Draw a label with a name below the face
         cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
-        if(proba > threshold):
+        if proba > threshold:
             font = cv2.FONT_HERSHEY_DUPLEX
             cv2.putText(frame, "{} {:.2f}".format(name, proba), (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)
 

+ 54 - 0
verify_face_2.py

@@ -0,0 +1,54 @@
+import face_recognition
+import cv2
+import numpy as np
+import joblib
+import time
+import os
+
+clf = joblib.load('saved_model.pkl')
+classes = clf.classes_
+
+threshold = 0.65
+
+test_image = face_recognition.load_image_file(os.path.join('application_data', 'input_image', 'input_image2.jpg'))
+
+while True:
+
+    rgb_frame = test_image[:, :, ::-1]
+
+    # Find all the faces and face enqcodings in the frame of video
+    face_locations = face_recognition.face_locations(rgb_frame)
+    no = len(face_locations)
+    print("Number of faces detected: ", no)
+    face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)
+
+    # Loop through each face in this frame of video
+    for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
+        start_time = time.perf_counter_ns()
+        proba_list = clf.predict_proba([face_encoding])
+        end_time = time.perf_counter_ns()
+        process_time = end_time - start_time
+        i = np.argmax(proba_list)
+        proba = list(*proba_list)[i]
+        name = classes[i]
+        print(name, "{:.2f}".format(proba), proba_list, process_time)
+
+        # Draw a box around the face
+        cv2.rectangle(test_image, (left, top), (right, bottom), (0, 0, 255), 2)
+
+        # Draw a label with a name below the face
+        cv2.rectangle(test_image, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
+        if(proba > threshold):
+            font = cv2.FONT_HERSHEY_DUPLEX
+            cv2.putText(test_image, "{} {:.2f}".format(name, proba), (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)
+
+
+    # Display the resulting image
+    cv2.imshow('Video', test_image)
+
+    # Hit 'q' on the keyboard to quit!
+    if cv2.waitKey(1) & 0xFF == ord('q'):
+        break
+
+# Release handle to the webcam
+cv2.destroyAllWindows()