def recognise(): json_ = request.get_json(force=True) start_time = time.time() start_dtime = time.strftime('%m-%d-%y %H:%M:%S', time.localtime(start_time)) schema = { 'tokenNo': { 'type': 'string', 'empty': False, 'nullable': False }, 'application': { 'type': 'string', 'empty': False, 'nullable': False }, 'groupId': { 'type': 'string', 'empty': False, 'nullable': False }, 'userId': { 'type': 'string', 'empty': False, 'nullable': False }, 'base64Image': { 'type': 'string', 'empty': False, 'nullable': False }, 'imageCounter': { 'type': 'integer', 'empty': False, 'nullable': False }, 'imageShape': { 'type': 'list', 'empty': False, 'nullable': False, 'schema': { 'type': 'integer', } }, 'suspiciousFlag': { 'type': 'integer', 'empty': False, 'nullable': True, 'required': False } } v = Validator(schema) v.allow_unknown = True Response_json = {} ResponseCode = '' ResponseMessage = '' if not (v.validate(json_)): errors_list = v.errors for key in errors_list.keys(): if 'empty values' in errors_list[key][0]: ResponseCode = '5001' ResponseMessage = 'Missing mandatory field' if 'type' in errors_list[key][0]: ResponseCode = '5002' ResponseMessage = 'Invalid input field' tokenNo = json_['tokenNo'] application = json_['application'] eGroup = json_['groupId'] user = json_['userId'] imageCounter = json_['imageCounter'] if 'suspiciousFlag' in json_: suspiciousFlag = json_['suspiciousFlag'] else: suspiciousFlag = 1 app.logger.info( 'New recognition request, application: {}, user group: {}, user: {}'. format(application, eGroup, user)) # Invalid Query if ResponseCode != "": response = recognise_response_generator( tokenNo=tokenNo, application=application, groupId=eGroup, userId=user, imageCounter=imageCounter, start_time=start_time, start_dtime=start_dtime, responseCode=ResponseCode, responseMessage=ResponseMessage) return json.dumps(response), {'Content-Type': 'application/json'} # User not found if dbutils.check_user(application=application, groupName=eGroup, userName=user) == 0: response = recognise_response_generator( tokenNo=tokenNo, application=application, groupId=eGroup, userId=user, imageCounter=imageCounter, start_time=start_time, start_dtime=start_dtime, responseCode='1002', responseMessage='Person not found') return json.dumps(response), {'Content-Type': 'application/json'} frGroupId, frModelId, frUserId, userStatus = dbutils.get_fruserdetails( application=application, groupName=eGroup, userName=user) rec_model_path = os.path.join(cfg.dirc['RECOGNITION_MODELS'], application, eGroup, str(frModelId)) # SACode Not Present rec_path = os.path.join(rec_model_path, 'rec.pickle') le_path = os.path.join(rec_model_path, 'le.pickle') if not os.path.exists(rec_path): response = recognise_response_generator( tokenNo=tokenNo, application=application, groupId=eGroup, userId=user, imageCounter=imageCounter, start_time=start_time, start_dtime=start_dtime, responseCode='1001', responseMessage='Model load error') return json.dumps(response), {'Content-Type': 'application/json'} # Get the model and encoder name recogniser = pickle.loads(open(rec_path, "rb").read()) labelencoder = pickle.loads(open(le_path, "rb").read()) # Model not trained for user if user not in labelencoder.classes_: response = recognise_response_generator( tokenNo=tokenNo, application=application, groupId=eGroup, userId=user, imageCounter=imageCounter, start_time=start_time, start_dtime=start_dtime, responseCode='1003', responseMessage='Model not trained for user') return json.dumps(response), {'Content-Type': 'application/json'} # Base64 image decoding error try: image_64 = base64.b64decode(json_['base64Image']) image = np.array(Image.open(io.BytesIO(image_64))) image = cv2.cvtColor(image, cv2.COLOR_BGRA2RGB) # Image normalization norm_img = np.zeros((image.shape[0], image.shape[1])) norm_img = cv2.normalize(image, norm_img, 0, 255, cv2.NORM_MINMAX) if cfg.FLAG_STORE_RECOGNITION_IMAGES == 1: store_recognition_image(image, tokenNo, application, eGroup, user, imageCounter) except Exception as e: response = recognise_response_generator( tokenNo=tokenNo, application=application, groupId=eGroup, userId=user, imageCounter=imageCounter, start_time=start_time, start_dtime=start_dtime, responseCode='2001', responseMessage='Image corrupted') print(repr(e)) return json.dumps(response), {'Content-Type': 'application/json'} if np.any(norm_img): # -------- Spoof Detection Here --------# spoof_feat = [get_spoof_features(image)] spoof_feat2 = get_spoof_features2(image) photoSpoofProb = photoSpoofClf.predict_proba(spoof_feat2)[0][1] videoSpoofProb = videoSpoofClf.predict_proba(spoof_feat)[:, 1][0] print('Spoof probabilities; photo: {}, video: {}'.format( photoSpoofProb, videoSpoofProb)) if suspiciousFlag == 0: photoSpoofCutoff = cfg.PHOTO_SPOOF_CUTOFF_NONSUS videoSpoofCutoff = cfg.VIDEO_SPOOF_CUTOFF_NONSUS else: photoSpoofCutoff = cfg.PHOTO_SPOOF_CUTOFF_SUS videoSpoofCutoff = cfg.VIDEO_SPOOF_CUTOFF_SUS print( 'Suspicious Flag={}; Spoof cut-offs; photo: {}, video: {}'.format( suspiciousFlag, photoSpoofCutoff, videoSpoofCutoff)) photoSpoofPred = photoSpoofProb >= photoSpoofCutoff videoSpoofPred = videoSpoofProb >= videoSpoofCutoff if photoSpoofPred: response = recognise_response_generator( tokenNo=tokenNo, application=application, groupId=eGroup, userId=user, imageCounter=imageCounter, start_time=start_time, start_dtime=start_dtime, responseCode='4001', responseMessage='Spoof detected', spoofStatus='Spoof', spoofConfidence=photoSpoofProb, spoofType='Photo') return json.dumps(response), {'Content-Type': 'application/json'} if videoSpoofPred: response = recognise_response_generator( tokenNo=tokenNo, application=application, groupId=eGroup, userId=user, imageCounter=imageCounter, start_time=start_time, start_dtime=start_dtime, responseCode='4001', responseMessage='Spoof detected', spoofStatus='Spoof', spoofConfidence=videoSpoofProb, spoofType='Video') return json.dumps(response), {'Content-Type': 'application/json'} # -------- Face Recognition Here --------# faceBlob = cv2.dnn.blobFromImage(norm_img, 1.0 / 255, (96, 96), (0, 0, 0), swapRB=True, crop=False) face_embedder.setInput(faceBlob) vec = face_embedder.forward() # perform classification to recognize the face predictions = recogniser.predict_proba(vec)[0] j = np.argmax(predictions) recognition_prob = predictions[j] recognised_name = labelencoder.classes_[j] app.logger.info('Request for: {}, Recognised with: {}'.format( user, recognised_name)) spoof_prob = max(photoSpoofProb, videoSpoofProb) if recognised_name in cfg.DUMMY_USERNAMES: response = recognise_response_generator( tokenNo=tokenNo, application=application, groupId=eGroup, userId=user, imageCounter=imageCounter, start_time=start_time, start_dtime=start_dtime, responseCode='0000', responseMessage='Success', spoofStatus='Non Spoof', spoofConfidence=spoof_prob, spoofType='NA', recognitionStatus='Not Recognised') return json.dumps(response), {'Content-Type': 'application/json'} # get euclidean distance eucd = avg_euc(frModelId, recognised_name, vec.flatten()) app.logger.info('EUCD with user {}: {}'.format(recognised_name, eucd)) if recognised_name == user: response = recognise_response_generator( tokenNo=tokenNo, application=application, groupId=eGroup, userId=user, imageCounter=imageCounter, start_time=start_time, start_dtime=start_dtime, responseCode='0000', responseMessage='Success', spoofStatus='Non Spoof', spoofConfidence=spoof_prob, spoofType='NA', recognitionStatus='Recognised', recognitionConfidence=round(recognition_prob, 2), eucd=eucd) return json.dumps(response), {'Content-Type': 'application/json'} elif recognised_name != user: response = recognise_response_generator( tokenNo=tokenNo, application=application, groupId=eGroup, userId=user, imageCounter=imageCounter, start_time=start_time, start_dtime=start_dtime, responseCode='0000', responseMessage='Success', spoofStatus='Non Spoof', spoofConfidence=spoof_prob, spoofType='NA', recognitionStatus='Not Recognised', recognitionConfidence=round(recognition_prob, 2), eucd=eucd) return json.dumps(response), {'Content-Type': 'application/json'}
def onboard(): json_ = request.get_json(force=True) schema = { 'requestId': { 'type': 'string', 'empty': False, 'nullable': False }, 'requestType': { 'type': 'string', 'empty': False, 'nullable': False, 'allowed': ['New', 'Update'] }, 'applicationName': { 'type': 'string', 'empty': False, 'nullable': False }, 'groupId': { 'type': 'string', 'empty': False, 'nullable': False }, 'userId': { 'type': 'string', 'empty': False, 'nullable': False }, 'profile': { 'type': 'string', 'empty': False, 'nullable': False, 'allowed': cfg.ALL_FACE_PROFILES }, 'imageCount': { 'type': 'integer', 'empty': False, 'nullable': False }, 'images': { 'type': 'list', 'empty': False, 'nullable': False, 'schema': { 'type': 'dict', 'schema': { 'imageId': { 'type': 'string', 'empty': False, 'nullable': False }, 'imageData': { 'type': 'string', 'empty': False, 'nullable': False }, } } } } validator = Validator(schema) validator.allow_unknown = True ResponseCode = '' ResponseMessage = '' ResponseId = 'R_{}'.format(json_['requestId']) # Request validation if not (validator.validate(json_)): errors_list = validator.errors for key in errors_list.keys(): if 'empty values' in errors_list[key][0]: ResponseCode = '5001' ResponseMessage = 'Missing mandatory field' app.logger.error('Missing mandatory field') if 'type' in errors_list[key][0]: ResponseCode = '5002' ResponseMessage = 'Invalid input field type' app.logger.error('Invalid input field type') if 'unallowed' in errors_list[key][0]: ResponseCode = '5003' ResponseMessage = 'Invalid input field value' app.logger.error('Invalid input field value') Response_json = onboard_response_generator( responseId=ResponseId, responseCode=ResponseCode, responseMessage=ResponseMessage) return json.dumps(Response_json), { 'Content-Type': 'application/json' } application = json_['applicationName'] eGroup = json_['groupId'] user = json_['userId'] requestType = json_['requestType'] profile = json_['profile'] images = json_['images'] app.logger.info( '{} Onboard request, application: {} GroupId: {} UserId: {} Profile: {}' .format(requestType, application, eGroup, user, profile)) if requestType == "Update": if dbutils.check_egroup(application, eGroup) == 0: ResponseCode = '2001' ResponseMessage = 'User Group not found' app.logger.error('User Group not found') Response_json = onboard_response_generator( responseId=ResponseId, responseCode=ResponseCode, responseMessage=ResponseMessage) return json.dumps(Response_json), { 'Content-Type': 'application/json' } if dbutils.check_user(application, eGroup, user) == 0: ResponseCode = '2002' ResponseMessage = 'User not found' app.logger.error('User not found') Response_json = onboard_response_generator( responseId=ResponseId, responseCode=ResponseCode, responseMessage=ResponseMessage) return json.dumps(Response_json), { 'Content-Type': 'application/json' } if requestType == "New": if dbutils.check_user(application, eGroup, user) != 0: frGroupId, frModelId, frUserId, userStatus = dbutils.get_fruserdetails( application=application, groupName=eGroup, userName=user) if (userStatus == 'Onboarding Complete' or userStatus == 'Profiles Complete' ) and profile in cfg.MANDOTORY_FACE_PROFILES: ResponseCode = '2003' ResponseMessage = 'Invalid request' app.logger.error('Invalid request') Response_json = onboard_response_generator( responseId=ResponseId, responseCode=ResponseCode, responseMessage=ResponseMessage) return json.dumps(Response_json), { 'Content-Type': 'application/json' } images_accepted = [] accepted_image_count = 0 images_response = [] ind = 0 while ind < len( images) and accepted_image_count < cfg.ONBOARDING_IMAGE_THRESHOLD: img_dict = images[ind] img_response = {'imageId': img_dict['imageId']} try: image_64 = base64.b64decode(img_dict['imageData']) image = np.array(Image.open(io.BytesIO(image_64))) image = cv2.cvtColor(image, cv2.COLOR_BGRA2RGB) norm_img = np.zeros((image.shape[0], image.shape[1])) norm_img = cv2.normalize(image, norm_img, 0, 255, cv2.NORM_MINMAX) image = norm_img img_check = image_checks(image, profile) if img_check == -1: img_response['imageStatus'] = 'Check Failed' else: img_response['imageStatus'] = 'Accepted' accepted_image_count += 1 images_accepted.append({ 'imageId': img_dict['imageId'], 'image': image }) except Exception as e: img_response['imageStatus'] = 'Corrupt' app.logger.error('Corrupt Image') images_response.append(img_response) ind += 1 app.logger.error('Images accepted: {}'.format(accepted_image_count)) while ind < len(images): img_dict = images[ind] img_response = {'imageId': img_dict['imageId'], 'imageResponse': 'NA'} images_response.append(img_response) ind += 1 # Set ResponseCode and ResponseMessage if accepted_image_count == cfg.ONBOARDING_IMAGE_THRESHOLD: ResponseCode = '0000' ResponseMessage = 'Success' app.logger.info('Success') # Send required data to DBUpdate Method dbupdate_json = { 'requestType': requestType, 'applicationName': application, 'groupId': eGroup, 'userId': user, 'profile': profile, 'images': images_accepted } # Send onboarding request data to DBUpdate Redis Queue job = q.enqueue(onboard_request, args=(dbupdate_json, )) else: ResponseCode = '1000' ResponseMessage = 'Threshold Not Met' app.logger.info('Threshold Not Met') # Set response JSON Response_json = onboard_response_generator(responseId=ResponseId, responseCode=ResponseCode, responseMessage=ResponseMessage, imgCount=accepted_image_count, images=images_response) return json.dumps(Response_json), {'Content-Type': 'application/json'}
def statuschange(): json_ = request.get_json(force=True) schema = { 'requestId': { 'type': 'string', 'empty': False, 'nullable': False }, 'applicationName': { 'type': 'string', 'empty': False, 'nullable': False }, 'groupId': { 'type': 'string', 'empty': False, 'nullable': False }, 'userId': { 'type': 'string', 'empty': False, 'nullable': False }, 'changeUserStatus': { 'type': 'string', 'empty': False, 'nullable': False, 'allowed': ['DELETE', 'RESET'] }, } validator = Validator(schema) validator.allow_unknown = True Response_json = {} ResponseCode = '' ResponseMessage = '' # Request validation if not (validator.validate(json_)): errors_list = validator.errors for key in errors_list.keys(): if 'empty values' in errors_list[key][0]: ResponseCode = '5001' ResponseMessage = 'Missing mandatory field' app.logger.error('Missing mandatory field') if 'type' in errors_list[key][0]: ResponseCode = '5002' ResponseMessage = 'Invalid input field type' app.logger.error('Invalid input field type') if 'unallowed' in errors_list[key][0]: ResponseCode = '5003' ResponseMessage = 'Invalid input field value' app.logger.error('Invalid input field value') Response_json['responseId'] = 'R_{}'.format(json_['requestId']) Response_json['responseCode'] = ResponseCode Response_json['responseMessage'] = ResponseMessage return json.dumps(Response_json), { 'Content-Type': 'application/json' } Response_json['responseId'] = 'R_{}'.format(json_['requestId']) application = json_['applicationName'] eGroup = json_['groupId'] user = json_['userId'] newUserStatus = json_['changeUserStatus'] app.logger.info( 'New StatusChange({}) request, requestId: {}, application: {}'.format( newUserStatus, json_['requestId'], application)) if dbutils.check_egroup(application, eGroup) == 0: ResponseCode = '2001' ResponseMessage = 'User Group not found' app.logger.error('User Group not found') Response_json['responseCode'] = ResponseCode Response_json['responseMessage'] = ResponseMessage return json.dumps(Response_json), {'Content-Type': 'application/json'} if dbutils.check_user(application, eGroup, user) == 0: ResponseCode = '2002' ResponseMessage = 'User not found' app.logger.error('User not found') Response_json['responseCode'] = ResponseCode Response_json['responseMessage'] = ResponseMessage return json.dumps(Response_json), {'Content-Type': 'application/json'} updateResult = 0 frGroupId, frModelId, frUserId, userStatus = dbutils.get_fruserdetails( application=application, groupName=eGroup, userName=user) if newUserStatus == 'DELETE': updateResult = dbutils.delete_user(frModelId=frModelId, frUserId=frUserId) elif newUserStatus == 'RESET': updateResult = dbutils.delete_all_profiles(frUsedId=frUserId) if updateResult == 1: ResponseCode = '0000' ResponseMessage = 'Success' app.logger.error('Success') elif updateResult == 0: ResponseCode = '1000' ResponseMessage = 'DB Error' app.logger.error('DB Error') Response_json['responseCode'] = ResponseCode Response_json['responseMessage'] = ResponseMessage return json.dumps(Response_json), {'Content-Type': 'application/json'}
def statusquery(): json_ = request.get_json(force=True) schema = { 'requestId': { 'type': 'string', 'empty': False, 'nullable': False }, 'applicationName': { 'type': 'string', 'empty': False, 'nullable': False }, 'users': { 'type': 'list', 'empty': False, 'nullable': False, 'schema': { 'type': 'dict', 'schema': { 'groupId': { 'type': 'string', 'empty': False, 'nullable': False }, 'userId': { 'type': 'string', 'empty': False, 'nullable': False }, } } } } validator = Validator(schema) validator.allow_unknown = True Response_json = {} ResponseCode = '' ResponseMessage = '' # Request validation if not (validator.validate(json_)): errors_list = validator.errors for key in errors_list.keys(): if 'empty values' in errors_list[key][0]: ResponseCode = '5001' ResponseMessage = 'Missing mandatory field' app.logger.error('Missing mandatory field') if 'type' in errors_list[key][0]: ResponseCode = '5002' ResponseMessage = 'Invalid input field' app.logger.error('Invalid input field') Response_json['responseId'] = 'R_{}'.format(json_['requestId']) Response_json['responseCode'] = ResponseCode Response_json['responseMessage'] = ResponseMessage Response_json['users'] = None return json.dumps(Response_json), { 'Content-Type': 'application/json' } Response_json['responseId'] = 'R_{}'.format(json_['requestId']) application = json_['applicationName'] usersResponse = [] app.logger.info( 'New Status Query request, requestId: {}, application: {}'.format( json_['requestId'], application)) for user_dict in json_['users']: groupId = user_dict['groupId'] userId = user_dict['userId'] if dbutils.check_user(application, groupId, userId) == 1: # Generate response for user frGroupId, frModelId, frUserId, userStatus = dbutils.get_fruserdetails( application=application, groupName=groupId, userName=userId) userProfiles = dbutils.get_profiles(frUsedId=frUserId) app.logger.info(userStatus) app.logger.info(userProfiles) user_dict = { "groupId": groupId, "userId": userId, "userFound": "True", "userStatus": userStatus, } for prof in cfg.ALL_FACE_PROFILES: if prof in userProfiles: user_dict["{}Profile".format(prof)] = 'Complete' else: user_dict["{}Profile".format(prof)] = 'InComplete' usersResponse.append(user_dict) else: # Generate response when user doesn't exist user_dict = { "groupId": groupId, "userId": userId, "userFound": "False", "userStatus": "NA", "frontProfile": "NA", "leftProfile": "NA", "rightProfile": "NA", "topProfile": "NA", "bottomProfile": "NA", "gfrontProfile": "NA" } usersResponse.append(user_dict) ResponseCode = '0000' ResponseMessage = 'Completed' Response_json['responseId'] = 'R_{}'.format(json_['requestId']) Response_json['responseCode'] = ResponseCode Response_json['responseMessage'] = ResponseMessage Response_json['users'] = usersResponse return json.dumps(Response_json), {'Content-Type': 'application/json'}
def onboard_request(json_): if json_ is None: return 0 log_file = os.path.join(cfg.dirc['LOGS'], 'onboard-request', 'DBUpdate.log') logger = get_logger(log_file) start_time = time.time() requestType = json_['requestType'] application = json_['applicationName'] eGroup = json_['groupId'] user = json_['userId'] profile = json_['profile'] logger.info( '{} - {} request for {}-{}-{} profile: {}'.format(datetime.now().strftime("%d/%m/%Y %H:%M:%S"), requestType, application, eGroup, user, profile)) frGroupId = None frModelId = None frUserId = None if requestType == 'New': # dbutils.delete_profile(application, eGroup, user, profile) if dbutils.check_egroup(application, eGroup) == 0: # create first model for usergroups dbutils.insert_egroup(application=application, eGroup=eGroup) frGroupId = dbutils.get_frgroupid(application, eGroup) dbutils.insert_frmodel(frGroupId=frGroupId, frModelNo=1) frGroupId = dbutils.get_frgroupid(application, eGroup) if dbutils.check_user(application=application, groupName=eGroup, userName=user) == 0: frModelId = dbutils.assign_frmodel(frGroupId) dbutils.insert_user(frModelId, user) dbutils.update_modelusercount(frModelId) frGroupId, frModelId, frUserId, userStatus = dbutils.get_fruserdetails(application, eGroup, user) elif requestType == 'Update': frGroupId, frModelId, frUserId, userStatus = dbutils.get_fruserdetails(application, eGroup, user) if ( userStatus == 'Onboarding Complete' or userStatus == 'Profiles Complete') and profile in cfg.MANDOTORY_FACE_PROFILES: dbutils.delete_all_profiles(frUsedId=frUserId) else: dbutils.delete_profile(frUserId=frUserId, profile=profile) # Generate augmentation of images and insert into table for img_dict in json_['images']: img = img_dict['image'] img_id = img_dict['imageId'] # changes in store_aumentations store_augmentations(logger, frUserId, profile, img, img_id) userStatus = dbutils.update_onboarding_status(frUserId) if userStatus == 'Profiles Complete' and application != cfg.DUMMY_APPLICATION_NAME: dbutils.set_model_retrain_flag(frModelId) logger.info('{} - Sending model retrain request for {}-{}, modelid: {}'.format( datetime.now().strftime("%d/%m/%Y %H:%M:%S"), application, eGroup, frModelId)) modelRetrainDict = {'application': application, 'groupId': eGroup, 'frModelId': frModelId} redis_conn = Redis(host=cfg.REDIS_HOST, port=cfg.REDIS_PORT) q = Queue(cfg.REDIS_RETRAIN_QUEUE, connection=redis_conn) # Send model retrain request data to model-retrain Redis Queue job = q.enqueue(retrain_model, args=(modelRetrainDict,)) redis_conn.connection_pool.disconnect() logger.info('Total time taken: {}'.format(time.time() - start_time)) return 1