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})
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)
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
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
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
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:")