from scipy.spatial.distance import cosine
import mtcnn
from keras.models import load_model
from utils import *
from data.results.mail import mail_alert



results_dir = "data/results/"
def recognize(img,
              detector,
              encoder,
              encoding_dict,
              recognition_t=0.5,
              confidence_t=0.99,
              required_size=(160, 160), ):
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    results = detector.detect_faces(img_rgb)

    count = 0
    for res in results:
        if res['confidence'] < confidence_t:
            continue
        face, pt_1, pt_2 = get_face(img_rgb, res['box'])
        encode = get_encode(encoder, face, required_size)
        encode = l2_normalizer.transform(encode.reshape(1, -1))[0]
        name = 'unknown'

        distance = float("inf")
        for db_name, db_encode in encoding_dict.items():
            dist = cosine(db_encode, encode)
            if dist < recognition_t and dist < distance:
                name = db_name
                distance = dist

        if name == 'unknown':
            cv2.rectangle(img, pt_1, pt_2, (0, 0, 255), 2)
            cv2.putText(img, name, pt_1, cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 1)
            
            # The count is a variable that modifies the file name
            count+=1
            """With a .copy on cropping the image it won't modify the underlying images"""
            cropped_unknown = img[pt_1[1]-60:pt_2[1]+20, pt_1[0]-20:pt_2[0]+20].copy()
            cv2.imwrite(results_dir+"unknown_"+(str(count)).zfill(5)+".jpg", cropped_unknown)
            
            #sending an email
            user = mail_alert()
            user.set_attach_path()
            user.send_mail()
            
        
        else:
            cv2.rectangle(img, pt_1, pt_2, (0, 255, 0), 2)
            cv2.putText(img, name + f'__{distance:.2f}', (pt_1[0], pt_1[1] - 5), cv2.FONT_HERSHEY_SIMPLEX, 1,
                        (0, 200, 200), 2)
    return img


if __name__ == '__main__':
    encoder_model = 'data/model/facenet_keras.h5'
    encodings_path = 'data/encodings/encodings.pkl'


    face_detector = mtcnn.MTCNN()
    face_encoder = load_model(encoder_model)
    encoding_dict = load_pickle(encodings_path)
    #video_path = '/home/davie/Desktop/demo.mp4'

    vc = cv2.VideoCapture(0)
    i = 0
    while vc.isOpened():
        ret, frame = vc.read()
        if not ret:
            print("no frame:(")
            break
        frame = recognize(frame, face_detector, face_encoder, encoding_dict)
        cv2.imshow('camera', frame)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

from scipy.spatial.distance import cosine
import mtcnn
from keras.models import load_model
from utils import *
from data.results.mail import mail_alert



results_dir = "data/results/"
def recognize(img,
              detector,
              encoder,
              encoding_dict,
              recognition_t=0.5,
              confidence_t=0.99,
              required_size=(160, 160), ):
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    results = detector.detect_faces(img_rgb)

    count = 0
    for res in results:
        if res['confidence'] < confidence_t:
            continue
        face, pt_1, pt_2 = get_face(img_rgb, res['box'])
        encode = get_encode(encoder, face, required_size)
        encode = l2_normalizer.transform(encode.reshape(1, -1))[0]
        name = 'unknown'

        distance = float("inf")
        for db_name, db_encode in encoding_dict.items():
            dist = cosine(db_encode, encode)
            if dist < recognition_t and dist < distance:
                name = db_name
                distance = dist

        if name == 'unknown':
            cv2.rectangle(img, pt_1, pt_2, (0, 0, 255), 2)
            cv2.putText(img, name, pt_1, cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 1)
            
            # The count is a variable that modifies the file name
            count+=1
            """With a .copy on cropping the image it won't modify the underlying images"""
            cropped_unknown = img[pt_1[1]-60:pt_2[1]+20, pt_1[0]-20:pt_2[0]+20].copy()
            cv2.imwrite(results_dir+"unknown_"+(str(count)).zfill(5)+".jpg", cropped_unknown)
            
            #sending an email
            user = mail_alert()
            user.set_attach_path()
            user.send_mail()
            
        
        else:
            cv2.rectangle(img, pt_1, pt_2, (0, 255, 0), 2)
            cv2.putText(img, name + f'__{distance:.2f}', (pt_1[0], pt_1[1] - 5), cv2.FONT_HERSHEY_SIMPLEX, 1,
                        (0, 200, 200), 2)
    return img


if __name__ == '__main__':
    encoder_model = 'data/model/facenet_keras.h5'
    encodings_path = 'data/encodings/encodings.pkl'


    face_detector = mtcnn.MTCNN()
    face_encoder = load_model(encoder_model)
    encoding_dict = load_pickle(encodings_path)
    #video_path = '/home/davie/Desktop/demo.mp4'

    vc = cv2.VideoCapture(0)
    i = 0
    while vc.isOpened():
        ret, frame = vc.read()
        if not ret:
            print("no frame:(")
            break
        frame = recognize(frame, face_detector, face_encoder, encoding_dict)
        cv2.imshow('camera', frame)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

# The count is a variable that modifies the file name With a .copy on cropping the image it won't modify the underlying images #sending an email #video_path = '/home/davie/Desktop/demo.mp4'