Exemple #1
0
 def get(self, request, format=None):
     try:
         job_id = uuid.uuid4()
         scan_photos(request.user, job_id)
         return Response({'status': True, 'job_id': job_id})
     except BaseException as e:
         logger.exception("An Error occured")
         return Response({'status': False})
Exemple #2
0
def geolocate(overwrite=False):
    if overwrite:
        photos = Photo.objects.all()
    else:
        photos = Photo.objects.filter(geolocation_json={})
    logger.info('%d photos to be geolocated' % photos.count())
    for photo in photos:
        try:
            logger.info('geolocating %s' % photo.image_path)
            photo._geolocate_mapbox()
        except:
            logger.exception('could not geolocate photo: ' + photo)
Exemple #3
0
def regenerate_event_titles(user, job_id):
    if LongRunningJob.objects.filter(job_id=job_id).exists():
        lrj = LongRunningJob.objects.get(job_id=job_id)
        lrj.started_at = datetime.now().replace(tzinfo=pytz.utc)
        lrj.save()
    else:
        lrj = LongRunningJob.objects.create(
            started_by=user,
            job_id=job_id,
            queued_at=datetime.now().replace(tzinfo=pytz.utc),
            started_at=datetime.now().replace(tzinfo=pytz.utc),
            job_type=LongRunningJob.JOB_GENERATE_AUTO_ALBUM_TITLES)
        lrj.save()
    try:
        aus = AlbumAuto.objects.filter(owner=user).prefetch_related('photos')
        target_count = len(aus)
        for idx, au in enumerate(aus):
            logger.info('job {}: {}'.format(job_id, idx))
            au._autotitle()
            au.save()

            lrj.result = {
                'progress': {
                    "current": idx + 1,
                    "target": target_count
                }
            }
            lrj.save()

        status = True
        message = 'success'
        res = {'status': status, 'message': message}

        lrj.finished = True
        lrj.finished_at = datetime.now().replace(tzinfo=pytz.utc)
        lrj.save()
        logger.info('job {}: updated lrj entry to db'.format(job_id))

    except:
        logger.exception("An error occured")
        lrj.failed = True
        lrj.finished = True
        lrj.finished_at = datetime.now().replace(tzinfo=pytz.utc)
        lrj.save()

    return 1
Exemple #4
0
def generate_event_albums(user, job_id):
    if LongRunningJob.objects.filter(job_id=job_id).exists():
        lrj = LongRunningJob.objects.get(job_id=job_id)
        lrj.started_at = datetime.now().replace(tzinfo=pytz.utc)
        lrj.save()
    else:
        lrj = LongRunningJob.objects.create(
            started_by=user,
            job_id=job_id,
            queued_at=datetime.now().replace(tzinfo=pytz.utc),
            started_at=datetime.now().replace(tzinfo=pytz.utc),
            job_type=LongRunningJob.JOB_GENERATE_AUTO_ALBUMS)
        lrj.save()

    try:
        photos = Photo.objects.filter(owner=user).only('exif_timestamp')

        photos_with_timestamp = [(photo.exif_timestamp, photo)
                                 for photo in photos if photo.exif_timestamp]

        def group(photos_with_timestamp, dt=timedelta(hours=6)):
            photos_with_timestamp = sorted(photos_with_timestamp,
                                           key=lambda x: x[0])
            groups = []
            for idx, photo in enumerate(photos_with_timestamp):
                if len(groups) == 0:
                    groups.append([])
                    groups[-1].append(photo[1])
                else:
                    if photo[0] - groups[-1][-1].exif_timestamp < dt:
                        groups[-1].append(photo[1])
                    else:
                        groups.append([])
                        groups[-1].append(photo[1])
                logger.info('job {}: {}'.format(job_id, idx))
            return groups

        groups = group(photos_with_timestamp, dt=timedelta(days=1, hours=12))
        logger.info('job {}: made groups'.format(job_id))

        album_locations = []

        target_count = len(groups)

        date_format = "%Y:%m:%d %H:%M:%S"
        for idx, group in enumerate(groups):
            key = group[0].exif_timestamp
            logger.info(
                'job {}: processing auto album with date: '.format(job_id) +
                key.strftime(date_format))
            items = group
            if len(group) >= 2:
                qs = AlbumAuto.objects.filter(timestamp=key).filter(owner=user)
                if qs.count() == 0:
                    album = AlbumAuto(
                        created_on=datetime.utcnow().replace(tzinfo=pytz.utc),
                        owner=user)
                    album.timestamp = key
                    album.save()

                    locs = []
                    for item in items:
                        album.photos.add(item)
                        item.save()
                        if item.exif_gps_lat and item.exif_gps_lon:
                            locs.append([item.exif_gps_lat, item.exif_gps_lon])
                    if len(locs) > 0:
                        album_location = np.mean(np.array(locs), 0)
                        album_locations.append(album_location)
                        album.gps_lat = album_location[0]
                        album.gps_lon = album_location[1]
                    else:
                        album_locations.append([])
                    album._autotitle()
                    album.save()
                    logger.info('job {}: generated auto album {}'.format(
                        job_id, album.id))

            lrj.result = {
                'progress': {
                    "current": idx + 1,
                    "target": target_count
                }
            }
            lrj.save()

        status = True
        message = 'success'
        res = {'status': status, 'message': message}

        lrj.finished = True
        lrj.finished_at = datetime.now().replace(tzinfo=pytz.utc)
        lrj.save()

    except:
        logger.exception("An error occured")
        lrj.failed = True
        lrj.finished = True
        lrj.finished_at = datetime.now().replace(tzinfo=pytz.utc)
        lrj.save()

    return 1
Exemple #5
0
def train_faces(user, job_id):
    if LongRunningJob.objects.filter(job_id=job_id).exists():
        lrj = LongRunningJob.objects.get(job_id=job_id)
        lrj.started_at = datetime.datetime.now().replace(tzinfo=pytz.utc)
        lrj.save()
    else:
        lrj = LongRunningJob.objects.create(
            started_by=user,
            job_id=job_id,
            queued_at=datetime.datetime.now().replace(tzinfo=pytz.utc),
            started_at=datetime.datetime.now().replace(tzinfo=pytz.utc),
            job_type=LongRunningJob.JOB_TRAIN_FACES)
        lrj.save()

    try:
        faces = Face.objects.filter(
            photo__owner=user).prefetch_related('person')

        id2face_unknown = {}
        id2face_known = {}
        face_encodings_unknown = []
        face_encodings_known = []
        face_encodings_all = []

        for face in faces:
            face_encoding = np.frombuffer(bytes.fromhex(face.encoding))
            face_image = face.image.read()
            face.image.close()
            face_image_path = face.image_path
            face_id = face.id
            face_encodings_all.append(face_encoding)
            if face.person_label_is_inferred is not False or face.person.name == 'unknown':
                face_encodings_unknown.append(face_encoding)
                id2face_unknown[face_id] = {}
                id2face_unknown[face_id]['encoding'] = face_encoding
                id2face_unknown[face_id]['image'] = face_image
                id2face_unknown[face_id]['image_path'] = face_image_path
                id2face_unknown[face_id]['id'] = face_id
            else:
                person_name = face.person.name
                person_id = face.person.id
                face_encodings_known.append(face_encoding)
                id2face_known[face_id] = {}
                id2face_known[face_id]['encoding'] = face_encoding
                id2face_known[face_id]['image'] = face_image
                id2face_known[face_id]['image_path'] = face_image_path
                id2face_known[face_id]['person_name'] = person_name
                id2face_known[face_id]['person_id'] = person_id
        
        if(len(id2face_known) == 0):
            logger.warning("No labeled faces found")
            lrj.finished = True
            lrj.failed = False
            lrj.finished_at = datetime.datetime.now().replace(tzinfo=pytz.utc)
            lrj.save()
            return True
        
        face_encodings_known = np.array(
            [f['encoding'] for f in id2face_known.values()])
        person_names_known = np.array(
            [f['person_name'] for f in id2face_known.values()])
        logger.info("Before fitting")        
        clf = MLPClassifier(
            solver='adam', alpha=1e-5, random_state=1, max_iter=1000).fit(face_encodings_known, person_names_known)
        logger.info("After fitting")    
        face_encodings_unknown = np.array(
            [f['encoding'] for f in id2face_unknown.values()])

        face_ids_unknown = [f['id'] for f in id2face_unknown.values()]
        pred = clf.predict(face_encodings_unknown)
        probs = np.max(clf.predict_proba(face_encodings_unknown), 1)

        target_count = len(face_ids_unknown)

        for idx, (face_id, person_name, probability) in enumerate(zip(face_ids_unknown, pred, probs)):
            person = Person.objects.get(name=person_name)
            face = Face.objects.get(id=face_id)
            face.person = person
            face.person_label_is_inferred = True
            face.person_label_probability = probability
            face.save()

            lrj.result = {
                'progress': {
                    "current": idx + 1,
                    "target": target_count
                }
            }
            lrj.save()

        lrj.finished = True
        lrj.failed = False
        lrj.finished_at = datetime.datetime.now().replace(tzinfo=pytz.utc)
        lrj.save()
        cache.clear()
        return True

    except BaseException:
        logger.exception("An error occured")
        res = []

        lrj.failed = True
        lrj.finished = True
        lrj.finished_at = datetime.datetime.now().replace(tzinfo=pytz.utc)
        lrj.save()
        return False

    return res
Exemple #6
0
def inference_places365(img_path, confidence):
    """
    @param img_path: path to the image to generate labels from
    @param confidence: minimum confidence before an category is selected
    @return: {'environment': 'indoor'/'outdoor', 'categories': [...], 'attributes': [...]}
    """
    try:

        def hook_feature(module, input, output):
            features_blobs.append(np.squeeze(output.data.cpu().numpy()))

        def load_model(
        ):  # TODO Should the model be reloaded for every photo? Wouldn't it be better to do that once?
            # this model has a last conv feature map as 14x14
            model_file = os.path.join(dir_places365_model,
                                      'wideresnet18_places365.pth.tar')
            model = wideresnet.resnet18(num_classes=365)
            checkpoint = torch.load(model_file,
                                    map_location=lambda storage, loc: storage)
            state_dict = {
                str.replace(k, 'module.', ''): v
                for k, v in checkpoint['state_dict'].items()
            }
            model.load_state_dict(state_dict)
            model.eval()
            # hook the feature extractor
            features_names = ['layer4', 'avgpool'
                              ]  # this is the last conv layer of the resnet
            for name in features_names:
                model._modules.get(name).register_forward_hook(hook_feature)
            return model

        # load the model
        features_blobs = []
        model = load_model()

        # load the transformer
        tf = returnTF()  # image transformer

        # get the softmax weight
        params = list(model.parameters())
        weight_softmax = params[-2].data.numpy()
        weight_softmax[weight_softmax < 0] = 0

        # load the test image
        #img_url = 'http://places2.csail.mit.edu/imgs/3.jpg'
        #os.system('wget %s -q -O test.jpg' % img_url)
        img = Image.open(img_path)
        # Normalize the image for processing
        input_img = V(tf(img).unsqueeze(0))

        # forward pass
        logit = model.forward(input_img)
        h_x = F.softmax(logit, 1).data.squeeze()
        probs, idx = h_x.sort(0, True)
        probs = probs.numpy()
        idx = idx.numpy()

        res = {}

        # output the IO prediction
        # labels_IO[idx[:10]] returns a list of 0's and 1's: 0 -> inside, 1 -> outside
        # Determine the mean to reach a consensus
        io_image = np.mean(labels_IO[idx[:10]])
        if io_image < 0.5:
            res['environment'] = 'indoor'
        else:
            res['environment'] = 'outdoor'

        # output the prediction of scene category
        # idx[i] returns a index number for which class it corresponds to
        # classes[idx[i]], thus returns the class name
        # idx is sorted together with probs, with highest probabilities first
        res['categories'] = []
        for i in range(0, 5):
            if probs[i] > confidence:
                res['categories'].append(
                    remove_nonspace_separators(classes[idx[i]]))
            else:
                break
        # TODO Should be replaced with more meaningful tags in the future
        # output the scene attributes
        # This is something I don't quiet grasp yet
        # Probs is not usable here anymore, we're not processing our input_image
        # Take the dot product of out W_attribute model and the feature blobs
        # And sort it along the -1 axis
        # This results in idx_a, with the last elements the index numbers of attributes, we have the most confidence in
        # Can't seem to get any confidence values, also all the attributes it detect are not really meaningful i.m.o.
        responses_attribute = W_attribute.dot(features_blobs[1])
        idx_a = np.argsort(responses_attribute)
        res['attributes'] = []
        for i in range(-1, -10, -1):
            res['attributes'].append(
                remove_nonspace_separators(labels_attribute[idx_a[i]]))

        return res
    except Exception:
        logger.exception("Error:")