The problem originated because of the nature of the code.
model = SVC(kernel='linear', probability=True)
class_names = [cls.name.replace('_', ' ') for cls in img_data]
As you see the code uses a SVC (Support Vector Classifier) to classify the classes. The SVC (or SVM) does not have an extra class for
threshold variable, it is used in face detection, aka drawing a bounding box around the face for FaceNet to classify it.
frame = frame[:, :, 0:3]
bounding_boxes, _ = detect_face.detect_face(frame, minsize, pnet, rnet, onet, threshold, factor)
nrof_faces = bounding_boxes.shape
As you can see, the
threshold variable is only used in detecting the bounding box.
Code for getting class name:
predictions = model.predict_proba(emb_array)
best_class_indices = np.argmax(predictions, axis=1)
best_class_probabilities = predictions[np.arange(len(best_class_indices)), best_class_indices]
cv2.rectangle(frame, (bb[i], bb[i]), (bb[i], bb[i]), (0, 255, 0), 2) #boxing face
#plot result idx under box
text_x = bb[i]
text_y = bb[i] + 20
print('Result Indices: ', best_class_indices)
You can see that no
unknown class can be found.
You can try adding another threshold value and check if the
predictions maximum value is lower than the threshold value. I have little experience in tensor flow so this is just a proof of concept, not sure if it will work.
best_class_probabilities = predictions[np.arange(len(best_class_indices)), best_class_indices] #original code
if(best_class_probabilities < threshold_2):
best_class_indices = -1
HumanNames = "unknown"
By the way, because of the nature of triplet loss, you don't have to add and extra class to the SVC/SVM as the embedding model is locked and not trained, so unknown class embeddings will be very different to the known class. However you can try either approach.
Hope it can help you can have a nice day!