CoolFace
Apppublic

amish24/Face_Features_Extraction

sourceHugging Faceupdated 3y agoView on Hugging Face
0likes
app.py242 linesDownload Raw Back to root
1import cv22from transformers import ViTImageProcessor, ViTForImageClassification, AutoModelForImageClassification, AutoImageProcessor3import torch 4import numpy as np5# import face_recognition6import subprocess7import sys8# subprocess.check_call([sys.executable, "-m", "pip", "install", 'git+https://github.com/bit-guber/retinaface.git', "--force-reinstall"])9 10# from retinaface import RetinaFace11 12from deepface import DeepFace13 14torch.backends.cudnn.benchmark = True15 16import urllib.request17path = 'https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml'18urllib.request.urlretrieve(path, path.split('/')[-1])19 20face_cascade = cv2.CascadeClassifier('./haarcascade_frontalface_default.xml')21 22class Base:23    size = 22424    scale = 1. / 255.25    mean = np.array( [ .5 ] * 3 ).reshape( 1, 1, 1, -1)26    std  = np.array( [ .5 ] * 3 ).reshape( 1, 1, 1, -1)27    resample = 228    29class ethnicityConfig(Base):30    size = 38431    32class maskConfig(Base):33    resample = 334    mean = np.array( [ .485 ] * 3 ).reshape( 1, 1, 1, -1)35    std  = np.array( [ .229 ] * 3 ).reshape( 1, 1, 1, -1)36 37 38AGE = "nateraw/vit-age-classifier"39GENDER = 'rizvandwiki/gender-classification-2'40ETHNICITY = 'cledoux42/Ethnicity_Test_v003'41MASK = 'DamarJati/Face-Mask-Detection'42BLUR = 'WT-MM/vit-base-blur'43BEARD = 'dima806/beard_face_image_detection'44 45 46device = 'cuda' if torch.cuda.is_available() else 'cpu'47# base_processor = ViTImageProcessor.from_pretrained( global_path + 'base_processor' )48age_model      = ViTForImageClassification.from_pretrained( AGE ).to(device)49gender_model   = ViTForImageClassification.from_pretrained( GENDER ).to(device)50beard_model    = ViTForImageClassification.from_pretrained( BEARD ).to(device)51blur_model     = ViTForImageClassification.from_pretrained( BLUR ).to(device)52 53# ethnicity_precessor = ViTImageProcessor.from_pretrained( global_path + 'ethnicity' )54ethnicity_model= ViTForImageClassification.from_pretrained( ETHNICITY ).to(device)55 56# mask_processor = ViTImageProcessor.from_pretrained( global_path + 'mask' )57mask_model     = AutoModelForImageClassification.from_pretrained( MASK ).to(device)58 59 60from PIL import Image61def normalize( data, mean, std ): # (batchs, nchannels, height, width)62    data =  (data - mean  ) / std63    return data.astype(np.float32)64 65def resize( image, size = 224, resample = 2  ):66#     if isinstance(iamge, np.ndarray):67#         image = Image.fromarray( image, mode = 'RGB' )68    69    image = image.resize( (size, size), resample = resample )70    71    return np.array( image )72 73def rescale( data, scale = Base.scale ):74    return data * scale75 76# resize 77# rescale78# normalize79 80def ParallelBatchsPredict( data, MODELS, nbatchs = 16 ):81    82    total = data.shape[0]83    # for change channel axis to first format84    data = np.transpose( data, ( 0, 3, 1, 2 ) )85    count = 086    batchs = [ [] for i in range(len(MODELS)) ]87    for i in range( 0, total, nbatchs ):88        batch = data[i:i+nbatchs]89        count += batch.shape[0]90        with torch.no_grad():91            batch = torch.from_numpy( batch ).to(device)92            for _, model in enumerate(MODELS):93                logits = model( batch ).logits.softmax(1).argmax(1).tolist()94                for x in logits:95                    batchs[_].append( model.config.id2label[ x ] )96 97    assert count == total98    return batchs99# model arrange100# age 101# gender102# blur103# beard104# changle processor105# Ethnicity106# change processor107# Mask108def AnalysisFeatures(rawFaces): # list[ PIL.Image ]109    110    if len(rawFaces) == 0:111        return [ [] ]* 6112    baseProcessed = np.array([ resize(x, size = Base.size, resample = Base.resample ) for x in  rawFaces])113    baseProcessed = rescale( baseProcessed )114    baseProcessed = normalize( baseProcessed, Base.mean, Base.std )115    116    ages, genders, beards, blurs = ParallelBatchsPredict(baseProcessed,  [age_model, gender_model, beard_model, blur_model]  )117    118    EthncityProcessed = np.array([ resize(x, size = ethnicityConfig.size, resample = ethnicityConfig.resample ) for x in  rawFaces])119    EthncityProcessed = rescale( EthncityProcessed )120    EthncityProcessed = normalize( EthncityProcessed, ethnicityConfig.mean, ethnicityConfig.std )121    122    ethncities = ParallelBatchsPredict(EthncityProcessed, [ethnicity_model])[0]123    124    125    MaskProcessed = np.array([ resize(x, size = maskConfig.size, resample = maskConfig.resample ) for x in  rawFaces])126    MaskProcessed = rescale( MaskProcessed )127    MaskProcessed = normalize( MaskProcessed, maskConfig.mean, maskConfig.std )128    129    masks = ParallelBatchsPredict(MaskProcessed, [mask_model])[0] 130    131    beards = [True if beard == 'Beard' else False for beard in beards]132    blurs  = [True if blur == 'blurry' else False for blur in blurs]133    masks  = [True if mask == 'WithMask' else False for mask in masks]134    135    return ages, genders, beards, blurs, ethncities, masks136 137 138import gradio as gr139 140def frameWrapper( facesCo, ages, genders, beards, blurs, ethncities, masks ):141    return { 'identifiedPersonCount': len(facesCo), 'value': [ { 'coordinate': { 'x': x, 'y': y, 'h': h, 'w':w }, 'ageGroup': age, 'gender': gender, 'beardPresent':beard, 'blurOccur': blur, 'ethncity': ethncity, 'maskPresent': mask } for (x, y, w, h), age, gender, beard, blur, ethncity, mask in zip( facesCo, ages, genders, beards, blurs, ethncities, masks ) ] }142 143def postProcessed( rawfaces, maximunSize, minSize = 30 ):144    faces = []145    for (x, y, w, h) in rawfaces:146        x1 = x if x<maximunSize[0] else maximunSize[0]147        y1 = y if y<maximunSize[1] else maximunSize[1]148        x2 = w+x if w+x<maximunSize[0] else maximunSize[0]149        y2 = h+y if h+y<maximunSize[1] else maximunSize[1]150        151        if x2-x1 > minSize and y2-y1 >minSize:152            faces.append( (x, y, w, h) )153    return faces154def image_inference(image):155 156    157    if sum(image.shape) == 0:158        return image, { 'ErrorFound': 'ImageNotFound' }159    # Convert into grayscale160    # gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)161    # Detect faces162    # rawfaces = face_cascade.detectMultiScale(gray, 1.05, 5, minSize = (30, 30))163    # image = np.asarray( image )164    # Draw rectangle around the faces165    # rawfaces = postProcessed( rawfaces, image.shape[:2] )166    167    # rawfaces = face_recognition.face_locations( image, number_of_times_to_upsample = 1 , model="hog")168    # rawfaces = []169    # for name, keys in RetinaFace.detect_faces( image ).items():170    #     rawfaces.append( keys['facial_area']  )171    # faces = [ image[top:bottom, left:right].copy() for (top, left, bottom, right) in rawfaces ]172    # faces = RetinaFace.extract_faces( image, align = True)173    # faces_mean = [ x.mean() for x in faces ]174    rawfaces = DeepFace.extract_faces( image )175    faces = [ x['face'] for x in  rawfaces]176    rawfaces = [ (x['facial_area']['x'], x['facial_area']['y'], x['facial_area']['w'], x['facial_area']['h']) for x in rawfaces ]177    # faces = [ image[x:w+x, y:h+y].copy() for (x, y, w, h) in rawfaces ]178    faces = [ Image.fromarray(x, mode = 'RGB') for x in faces ]179    ages, genders, beards, blurs, ethncities, masks = AnalysisFeatures( faces )180 181    annotatedImage = image.copy()182    for (x, y, w, h) in rawfaces:183        cv2.rectangle(annotatedImage, (x, x+w), (y, y+h), (255, 0, 0), 5)184 185    return Image.fromarray(annotatedImage, mode = 'RGB'), frameWrapper( rawfaces, ages, genders, beards, blurs, ethncities, masks )186    # return frameWrapper( rawfaces, ages, genders, beards, blurs, ethncities, masks )187def video_inference(video_path):188    189    global_facesCo = []190    global_faces = []191    cap = cv2.VideoCapture(video_path)192    frameCount = 0193    while(cap.isOpened()):194        _, img = cap.read()195        196        # try:197        # Convert into grayscale198            # gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)199        # except:200            # break201        # Detect faces202        # rawfaces = face_cascade.detectMultiScale(gray, 1.05, 6, minSize = (30, 30))203        try:204            image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)205            image = np.asarray( image )206        except:207            break208        # rawfaces = postProcessed( rawfaces, image.shape[:2] )209        rawfaces = []210        for name, keys in RetinaFace.detect_faces( image ).items():211            rawfaces.append( keys['facial_area']  )212        213        # rawfaces = face_recognition.face_locations( image, number_of_times_to_upsample = 1 , model="hog")214        # Draw rectangle around the faces215        # https://stackoverflow.com/questions/15589517/how-to-crop-an-image-in-opencv-using-python for fliping axis 216        global_facesCo.append( rawfaces )217        for (top, left, bottom, right) in rawfaces:218            # face = image[x:w+x, y:h+y].copy()219            face = image[top:bottom, left:right].copy()220            global_faces.append(Image.fromarray( face , mode = 'RGB') ) 221    222    ages, genders, beards, blurs, ethncities, masks = AnalysisFeatures( global_faces )223    224    total_extraction = []225    for facesCo in global_facedsCo:226        length = len(facesCo)227        228        total_extraction.append( frameWrapper( facesCo, ages[:length], genders[:length], beards[:length], blurs[:length], ethncities[:length], masks[:length]  ) )229        230        ages, genders, beards, blurs, ethncities, masks = ages[length:], genders[length:], beards[length:], blurs[length:], ethncities[length:], masks[length:]231    return total_extraction232 233css = """234    .outputJSON{235        overflow: scroll;236    }237    """238imageHander = gr.Interface( fn = image_inference, inputs = gr.Image(type="numpy", sources = 'upload'), outputs = ['image', gr.JSON(elem_classes = 'outputJSON')], css = css )239videoHander = gr.Interface( fn = video_inference, inputs = gr.Video(sources = 'upload', max_length = 30, include_audio = False), outputs = 'json' )240demo = gr.TabbedInterface( [imageHander, videoHander], tab_names = [ 'Image-to-Features', 'Video-to-Features' ], title = 'Facial Feature Extraction' )241 242demo.launch()