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)
Пример #2
0
    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)
Пример #3
0
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)
Пример #5
0
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)
Пример #6
0
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()