U
    ¥A{iÇ(  ã                   @   s0  d dl Zd dlZd dlZd dlmZ zd dlZW n* ek
rZ   edƒ edƒ e	ƒ  Y nX de_
e ¡ Ze ¡ Ze e¡Ze ¡ Ze e¡Ze ¡ Ze e¡Ze ¡ Ze e¡Zdd„ Zdd	„ Zd
d„ Zdd„ Zd'dd„Z d(dd„Z!d)dd„Z"d*dd„Z#d+dd„Z$d,dd„Z%d-dd „Z&d.d"d#„Z'd/d%d&„Z(dS )0é    N)Ú	ImageFilez\Please install `face_recognition_models` with this command before using `face_recognition`:
zCpip install git+https://github.com/ageitgey/face_recognition_modelsTc                 C   s   |   ¡ |  ¡ |  ¡ |  ¡ fS )zÜ
    Convert a dlib 'rect' object to a plain tuple in (top, right, bottom, left) order

    :param rect: a dlib 'rect' object
    :return: a plain tuple representation of the rect in (top, right, bottom, left) order
    )ÚtopÚrightZbottomÚleft)Úrect© r   ú8/tmp/pip-unpacked-wheel-pbnq7y3j/face_recognition/api.pyÚ_rect_to_css    s    r	   c                 C   s    t  | d | d | d | d ¡S )zÔ
    Convert a tuple in (top, right, bottom, left) order to a dlib `rect` object

    :param css:  plain tuple representation of the rect in (top, right, bottom, left) order
    :return: a dlib `rect` object
    é   r   é   é   )ÚdlibZ	rectangle)Úcssr   r   r   Ú_css_to_rect*   s    r   c                 C   s<   t | d dƒt| d |d ƒt| d |d ƒt | d dƒfS )aX  
    Make sure a tuple in (top, right, bottom, left) order is within the bounds of the image.

    :param css:  plain tuple representation of the rect in (top, right, bottom, left) order
    :param image_shape: numpy shape of the image array
    :return: a trimmed plain tuple representation of the rect in (top, right, bottom, left) order
    r   r   r   r
   )ÚmaxÚmin)r   Zimage_shaper   r   r   Ú_trim_css_to_bounds4   s    r   c                 C   s*   t | ƒdkrt d¡S tjj| | dd�S )a”  
    Given a list of face encodings, compare them to a known face encoding and get a euclidean distance
    for each comparison face. The distance tells you how similar the faces are.

    :param faces: List of face encodings to compare
    :param face_to_compare: A face encoding to compare against
    :return: A numpy ndarray with the distance for each face in the same order as the 'faces' array
    r   r   )Zaxis)ÚlenÚnpÚemptyZlinalgZnorm)Úface_encodingsZface_to_comparer   r   r   Úface_distance?   s    	
r   ÚRGBc                 C   s$   t j | ¡}|r| |¡}t |¡S )a#  
    Loads an image file (.jpg, .png, etc) into a numpy array

    :param file: image file name or file object to load
    :param mode: format to convert the image to. Only 'RGB' (8-bit RGB, 3 channels) and 'L' (black and white) are supported.
    :return: image contents as numpy array
    )ÚPILZImageÚopenÚconvertr   Úarray)ÚfileÚmodeZimr   r   r   Úload_image_fileN   s    
r   r   Úhogc                 C   s    |dkrt | |ƒS t| |ƒS dS )a  
    Returns an array of bounding boxes of human faces in a image

    :param img: An image (as a numpy array)
    :param number_of_times_to_upsample: How many times to upsample the image looking for faces. Higher numbers find smaller faces.
    :param model: Which face detection model to use. "hog" is less accurate but faster on CPUs. "cnn" is a more accurate
                  deep-learning model which is GPU/CUDA accelerated (if available). The default is "hog".
    :return: A list of dlib 'rect' objects of found face locations
    ÚcnnN)Úcnn_face_detectorÚface_detector©ÚimgÚnumber_of_times_to_upsampleÚmodelr   r   r   Ú_raw_face_locations\   s    

r(   c                    s@   |dkr"‡ fdd„t ˆ |dƒD ƒS ‡ fdd„t ˆ ||ƒD ƒS dS )a7  
    Returns an array of bounding boxes of human faces in a image

    :param img: An image (as a numpy array)
    :param number_of_times_to_upsample: How many times to upsample the image looking for faces. Higher numbers find smaller faces.
    :param model: Which face detection model to use. "hog" is less accurate but faster on CPUs. "cnn" is a more accurate
                  deep-learning model which is GPU/CUDA accelerated (if available). The default is "hog".
    :return: A list of tuples of found face locations in css (top, right, bottom, left) order
    r!   c                    s   g | ]}t t|jƒˆ jƒ‘qS r   ©r   r	   r   Úshape©Ú.0Úface©r%   r   r   Ú
<listcomp>w   s     z"face_locations.<locals>.<listcomp>c                    s   g | ]}t t|ƒˆ jƒ‘qS r   )r   r	   r*   r+   r.   r   r   r/   y   s     N)r(   r$   r   r.   r   Úface_locationsl   s    
r0   é€   c                 C   s   t | ||d�S )aa  
    Returns an 2d array of dlib rects of human faces in a image using the cnn face detector

    :param img: A list of images (each as a numpy array)
    :param number_of_times_to_upsample: How many times to upsample the image looking for faces. Higher numbers find smaller faces.
    :return: A list of dlib 'rect' objects of found face locations
    )Ú
batch_size)r"   )Úimagesr&   r2   r   r   r   Ú_raw_face_locations_batched|   s    r4   c                    s&   ‡ fdd„}t ˆ ||ƒ}tt||ƒƒS )a‡  
    Returns an 2d array of bounding boxes of human faces in a image using the cnn face detector
    If you are using a GPU, this can give you much faster results since the GPU
    can process batches of images at once. If you aren't using a GPU, you don't need this function.

    :param images: A list of images (each as a numpy array)
    :param number_of_times_to_upsample: How many times to upsample the image looking for faces. Higher numbers find smaller faces.
    :param batch_size: How many images to include in each GPU processing batch.
    :return: A list of tuples of found face locations in css (top, right, bottom, left) order
    c                    s   ‡ fdd„| D ƒS )Nc                    s"   g | ]}t t|jƒˆ d  jƒ‘qS )r   r)   r+   ©r3   r   r   r/   “   s     zObatch_face_locations.<locals>.convert_cnn_detections_to_css.<locals>.<listcomp>r   )Z
detectionsr5   r   r   Úconvert_cnn_detections_to_css’   s    z;batch_face_locations.<locals>.convert_cnn_detections_to_css)r4   ÚlistÚmap)r3   r&   r2   r6   Zraw_detections_batchedr   r5   r   Úbatch_face_locations‡   s    r9   Úlargec                    sD   |d krt ˆ ƒ}ndd„ |D ƒ}t‰|dkr0t‰‡ ‡fdd„|D ƒS )Nc                 S   s   g | ]}t |ƒ‘qS r   )r   ©r,   Zface_locationr   r   r   r/   ž   s     z'_raw_face_landmarks.<locals>.<listcomp>Úsmallc                    s   g | ]}ˆˆ |ƒ‘qS r   r   r;   ©Ú
face_imageZpose_predictorr   r   r/   ¥   s     )r(   Úpose_predictor_68_pointÚpose_predictor_5_point)r>   r0   r'   r   r=   r   Ú_raw_face_landmarksš   s    
rA   c                 C   sR   t | ||ƒ}dd„ |D ƒ}|dkr0dd„ |D ƒS |dkrFdd„ |D ƒS tdƒ‚dS )	aª  
    Given an image, returns a dict of face feature locations (eyes, nose, etc) for each face in the image

    :param face_image: image to search
    :param face_locations: Optionally provide a list of face locations to check.
    :param model: Optional - which model to use. "large" (default) or "small" which only returns 5 points but is faster.
    :return: A list of dicts of face feature locations (eyes, nose, etc)
    c                 S   s   g | ]}d d„ |  ¡ D ƒ‘qS )c                 S   s   g | ]}|j |jf‘qS r   )ÚxÚy)r,   Úpr   r   r   r/   ²   s     z-face_landmarks.<locals>.<listcomp>.<listcomp>)Úparts)r,   Zlandmarkr   r   r   r/   ²   s     z"face_landmarks.<locals>.<listcomp>r:   c                 S   sÚ   g | ]Ò}|d d… |dd… |dd… |dd… |dd… |dd… |dd… |dd… |d	 g |d
 g |d g |d g |d g |dd… |d g |d g |d g |d g |d g |d	 g dœ	‘qS )r   é   é   é   é   é$   é*   é0   é7   é@   é?   é>   é=   é<   é6   éC   éB   éA   )	ZchinZleft_eyebrowZright_eyebrowZnose_bridgeÚnose_tipÚleft_eyeÚ	right_eyeZtop_lipZ
bottom_lipr   ©r,   Zpointsr   r   r   r/   ¶   s   
÷






<F÷r<   c                 S   s.   g | ]&}|d  g|dd … |dd… dœ‘qS )é   r   r   )rW   rX   rY   r   rZ   r   r   r   r/   Â   s
   ý

ýzFInvalid landmarks model type. Supported models are ['small', 'large'].N)rA   Ú
ValueError)r>   r0   r'   Z	landmarksZlandmarks_as_tuplesr   r   r   Úface_landmarks¨   s    	
öür]   r<   c                    s    t ˆ ||ƒ}‡ ‡fdd„|D ƒS )aj  
    Given an image, return the 128-dimension face encoding for each face in the image.

    :param face_image: The image that contains one or more faces
    :param known_face_locations: Optional - the bounding boxes of each face if you already know them.
    :param num_jitters: How many times to re-sample the face when calculating encoding. Higher is more accurate, but slower (i.e. 100 is 100x slower)
    :param model: Optional - which model to use. "large" (default) or "small" which only returns 5 points but is faster.
    :return: A list of 128-dimensional face encodings (one for each face in the image)
    c              	      s    g | ]}t  t ˆ |ˆ¡¡‘qS r   )r   r   Úface_encoderZcompute_face_descriptor)r,   Zraw_landmark_set©r>   Únum_jittersr   r   r/   Ö   s     z"face_encodings.<locals>.<listcomp>)rA   )r>   Zknown_face_locationsr`   r'   Zraw_landmarksr   r_   r   r   Ë   s    
r   ç333333ã?c                 C   s   t t| |ƒ|kƒS )aé  
    Compare a list of face encodings against a candidate encoding to see if they match.

    :param known_face_encodings: A list of known face encodings
    :param face_encoding_to_check: A single face encoding to compare against the list
    :param tolerance: How much distance between faces to consider it a match. Lower is more strict. 0.6 is typical best performance.
    :return: A list of True/False values indicating which known_face_encodings match the face encoding to check
    )r7   r   )Zknown_face_encodingsZface_encoding_to_checkZ	tolerancer   r   r   Úcompare_facesÙ   s    	rb   )r   )r   r    )r   r    )r   r1   )r   r1   )Nr:   )Nr:   )Nr   r<   )ra   ))Z	PIL.Imager   r   Znumpyr   r   Zface_recognition_modelsÚ	ExceptionÚprintÚquitZLOAD_TRUNCATED_IMAGESZget_frontal_face_detectorr#   Zpose_predictor_model_locationZpredictor_68_point_modelZshape_predictorr?   Z(pose_predictor_five_point_model_locationZpredictor_5_point_modelr@   Z cnn_face_detector_model_locationZcnn_face_detection_modelZcnn_face_detection_model_v1r"   Zface_recognition_model_locationZface_recognition_modelZface_recognition_model_v1r^   r	   r   r   r   r   r(   r0   r4   r9   rA   r]   r   rb   r   r   r   r   Ú<module>   s@   












#
