def update_family_model(family_id, people): # Updating family model clear_directory(settings.FACE_RECOG_TRAIN_TEMP_DIR) # Getting Face Models for family face_model = FaceModel.objects.filter(family_id=family_id).first() if not face_model: # No face model, create new one process_family(family_id) else: X = pickle.loads(face_model.fit_data_faces) y = pickle.loads(face_model.fit_data_person_ids) files = [] for person in people: if person.large_thumbnail: file = download_file(settings.FACE_RECOG_TRAIN_TEMP_DIR, person.large_thumbnail) files.append(file) process_file(file, X, y, person.id) if len(files) > 0: face_model.update_knn_classifier(X, y)
def setUp(self): ''' Need to create a family and a gallery ''' self.family = Family() self.family.save() self.gallery = Gallery.objects.create(title="test_gallery", family_id=self.family.id) clear_directory(settings.FACE_RECOG_TRAIN_TEST_DIR) self.test_image = os.path.join( settings.BASE_DIR, 'facial_recognition/tests/test_image_woman.jpg') self.test_image_destination = ''.join([ settings.MEDIA_ROOT, 'galleries/', str(self.family.id), '/', str(self.gallery.id), '/test_image.jpg' ]) self.test_image_s3_key = ''.join([ 'galleries/', str(self.family.id), '/', str(self.gallery.id), '/test_image.jpg' ]) directory = ''.join([ settings.MEDIA_ROOT, 'galleries/', str(self.family.id), '/', str(self.gallery.id) ]) if not os.path.exists(directory): os.makedirs(directory) #Copy test image to media area shutil.copy2(self.test_image, self.test_image_destination) self.image = Image(gallery=self.gallery, family=self.family, original_image=''.join([ 'galleries/', str(self.family.id), '/', str(self.gallery.id), '/test_image.jpg' ])) self.image.save() self.image.upload_files_to_s3() self.person = Person(name='Wallace', gender='M', email='*****@*****.**', family_id=self.family.id, language='en') self.person.save() self.tag = Tag.objects.create(image_id=self.image.id, x1=0.279, y1=0.188, x2=0.536, y2=0.381, person_id=self.person.id, face_detected=True)
def process_family(family_id): ''' Creates a K Nearest neighbour model for a family using tagged photos and profile picture ''' #Clearing working directory clear_directory(settings.FACE_RECOG_TRAIN_TEMP_DIR) face_model = FaceModel(family_id=family_id) people = Person.objects.filter(family_id=family_id) X = [] y = [] # Gets X and y data for each person for person in people: process_person(person, X, y) if (len(X) > 0): face_model.update_knn_classifier(X, y) return face_model else: print('Not enough data to create model') return None
def update_family_model(family_id, tags): clear_directory(settings.FACE_RECOG_TRAIN_TEMP_DIR) # Getting Face Models for family face_model = FaceModel.objects.filter(family_id=family_id).first() if not face_model: # No face model, create new one process_family(family_id) else: X = pickle.loads(face_model.fit_data_faces) y = pickle.loads(face_model.fit_data_person_ids) files = [] for tag in tags: if tag.image.large_thumbnail: file = get_file_for_tag(tag, tag.image, settings.FACE_RECOG_TRAIN_TEMP_DIR) files.append(file) process_file(file, X, y, tag.person_id) if len(files) > 0: face_model.update_knn_classifier(X, y)
def resize_tags(messages): ''' Routine for resizing tags to match a recognized face ''' try: clear_directory(settings.FACE_RECOG_RESIZE_TAG_TEMP_DIR) db_images = dict() face_locations_by_image_id = dict() tag_ids = [] for message in messages: if message.integer_data: tag_ids.append(message.integer_data) tags = Tag.objects.filter(id__in=tag_ids).all() match_tags = 0 for tag in tags: tag_center = { 'x': (tag.x2 + tag.x1) / 2, 'y': (tag.y2 + tag.y1) / 2, } if tag.image_id in db_images: # Using cached image if already downloaded db_image = db_images[tag.image_id] local_file = get_file_name(settings.FACE_RECOG_TAG_TEMP_DIR, db_image.large_thumbnail) locations = face_locations_by_image_id[tag.image_id] else: #Get image db_image = Image.objects.get(id=tag.image_id) db_images[tag.image_id] = db_image #Download file local_file = download_file( settings.FACE_RECOG_RESIZE_TAG_TEMP_DIR, db_image.large_thumbnail) #Loading the file into a numpy array image = face_recognition.load_image_file(local_file) # Faces found in image locations = face_recognition.face_locations(image) face_locations_by_image_id[tag.image_id] = locations for location in locations: top, right, bottom, left = location x1 = left / db_image.large_thumbnail_width x2 = right / db_image.large_thumbnail_width y1 = top / db_image.large_thumbnail_height y2 = bottom / db_image.large_thumbnail_height # Make sure centre of original tag is in detected face if x1 < tag_center['x'] and tag_center['x'] < x2: if y1 < tag_center['y'] and tag_center['y'] < y2: match_tags += 1 # Update tag with facial detection tag.x1 = x1 tag.x2 = x2 tag.y1 = y1 tag.y2 = y2 tag.face_detected = True tag.save() # Messages processed for message in messages: message.processed = True message.save() except Exception as e: print(e) for message in messages: message.error = True message.error_message = str(e)[:512] message.save() clear_directory(settings.FACE_RECOG_RESIZE_TAG_TEMP_DIR)
def image_face_detect(messages): ''' Detects faces in images and suggest who they may be from trained family data ''' try: clear_directory(settings.FACE_RECOG_IMAGE_FACE_DETECT_TEMP_DIR) # Get all the image ids image_ids = [] for message in messages: if message.integer_data: image_ids.append(message.integer_data) # Get all database images db_images = Image.objects.filter(pk__in=image_ids) suggested_tag_count = 0 face_models = {} for db_image in db_images: # Download remote image file local_file = download_file( settings.FACE_RECOG_IMAGE_FACE_DETECT_TEMP_DIR, db_image.large_thumbnail) # Load image into memory image = face_recognition.load_image_file(local_file) # Find faces in image locations = face_recognition.face_locations(image) # Created a suggested tag for each detected face for location in locations: top, right, bottom, left = location # Normalize the location x1 = left / db_image.large_thumbnail_width x2 = right / db_image.large_thumbnail_width y1 = top / db_image.large_thumbnail_height y2 = bottom / db_image.large_thumbnail_height new_suggested_tag = SuggestedTag( image_id=db_image.id, x1=x1, x2=x2, y1=y1, y2=y2, last_updated_date=datetime.datetime.utcnow(), creation_date=datetime.datetime.utcnow()) # Load the face model for each family if db_image.family_id in face_models: face_model = face_models[db_image.family_id] else: face_model = FaceModel.objects.get( family_id=db_image.family_id) face_models[db_image.family_id] = face_model if face_model: # Find encodings for faces in the image faces_encodings = face_recognition.face_encodings( image, known_face_locations=(location, )) # Match a family member to the face # Load the training model (K nearest neighbours) trained_knn_model = pickle.loads( face_model.trained_knn_model) distances, fit_face_indexes = trained_knn_model.kneighbors( faces_encodings, n_neighbors=1) if len(distances) > 0 and len(distances[0]) > 0: fit_data_person_ids = pickle.loads( face_model.fit_data_person_ids) if len(fit_data_person_ids) > fit_face_indexes[0][0]: # Check person exists person_id = fit_data_person_ids[fit_face_indexes[0] [0]] if Person.objects.filter(pk=person_id).exists(): # Adding matched person new_suggested_tag.probability = distances[0][0] new_suggested_tag.person_id = person_id else: print( 'Invalid person_id: {}'.format(person_id)) new_suggested_tag.save() suggested_tag_count += 1 # Messages processed for message in messages: message.processed = True message.save() except: print(traceback.format_exc()) for message in messages: message.error = True message.error_message = str(traceback.format_exc())[:512] message.save()