def test_warp_img(): base = (300, 200) top = (100, 200) warped_path, warped_base, warped_top = warp_img(IMG_PATH, base, top) expected_warped_path = os.path.join(TEMP_FOLDER, 'platane-1_warped.jpeg') assert_equals(warped_path, expected_warped_path) assert_equals(warped_base, (450, 250)) assert_equals(warped_top, (25, 250)) assert_true(os.path.exists(warped_path)) # The resulting image has a fixed size assert_equals(get_img_size(warped_path), (500, 500))
def snapshot(request): """Index page.""" filename = request.matchdict['file'] settings = dict(request.registry.settings) pic_dir = settings['thumbs.document_root'] file_path = os.path.join(pic_dir, filename) try: height, width = get_img_size(file_path) except IOError: logger.error("Failed to open file with path: %s", file_path, exc_info=True) raise HTTPNotFound("Could not load image for snap %s" % filename) # security loop elmts = filename.split(os.sep) for unsecure in ('.', '..'): if unsecure in elmts: return HTTPNotFound() file_uuid = os.path.splitext(filename)[0] if request.method == 'POST': base = _toint(request.POST['bottom_y']), _toint(request.POST['bottom_x']) top = _toint(request.POST['top_y']), _toint(request.POST['top_x']) warped_img_path, new_base, new_top = warp_img(file_path, base, top) # There should be only one snap_idx, snap_type = 'snaps', 'snaptype' snap = request.db.get(snap_idx, snap_type, file_uuid) warped_filename = os.path.basename(warped_img_path) if snap is not None: snap['warped_filename'] = warped_filename snap['warped'] = True snap['base_x'] = base[0] snap['base_y'] = base[1] snap['top_x'] = top[0] snap['top_y'] = top[1] logger.debug("Warping snap %s", file_uuid) request.db.index(snap, snap_idx, snap_type, file_uuid) request.db.refresh() # Precompute the cached features incrementally compute_features_collection([snap], pic_dir, cache=FEATURES_CACHE) else: logger.warning("Could not find snap for %s", file_uuid) return HTTPFound(location='/warped/%s' % warped_filename) data = {'snapshot': filename, 'width': width, 'height': height} return _basic(request, data)
def warped(request): """Index page.""" filename = request.matchdict['file'] settings = dict(request.registry.settings) pic_dir = settings['thumbs.document_root'] orig_img = os.path.join(pic_dir, filename) res = get_img_size(orig_img) warped_stemname = os.path.splitext(filename)[0] snap_idx, snap_type = 'snaps', 'snaptype' if warped_stemname.endswith('_warped'): file_uuid = warped_stemname[:-len('_warped')] else: logger.warning( 'Warped stemname is expected to end with "_warped", got: %s', warped_stemname ) file_uuid = warped_stemname try: current_snap = request.db.get(snap_idx, snap_type, file_uuid) except NotFoundException: raise HTTPNotFound("Could not find snapshot for %s" % file_uuid) next_snap = None unwarped_count = "" if not current_snap.plant: query = FieldQuery(FieldParameter('warped', True)) candidates = request.db.search(query, size=200, indices=['snaps'], sort='timestamp:desc') # TODO: filter out non-plant snaps in the query directly candidates = [c for c in candidates if c.plant != None] logger.debug('Computing suggestion for %s', current_snap.filename) best_snaps, scores = suggest_snaps(current_snap, candidates, pic_dir, FEATURES_CACHE) suggestions = OrderedDict() for i, (snap, score) in enumerate(zip(best_snaps, scores)): name = snap.plant logger.debug("#%02d: %s with score = %f - %s", i, name, score, snap.filename) suggestion = suggestions.get(name) if suggestion is None: query = FieldQuery(FieldParameter('name', name)) plants = list(request.db.search(query, indices=['plants'])) if not plants: raise HTTPNotFound("No plant registered under %s" % name) plant = plants[0] suggestions[name] = (plant, [snap]) else: suggestion[1].append(snap) else: suggestions = None # Suggest to warp the next unwarped snapshot from the same plant query = FieldQuery(fieldparameters=( FieldParameter('warped', None), FieldParameter('filename', '-' + current_snap.filename), FieldParameter('plant', current_snap.plant))) max_count = 100 next_snaps = request.db.search({ "bool" : { "must" : [ {'field': {'filename': '-' + current_snap.filename}}, {'field': {'plant': current_snap.plant}}, ], "must_not" : [ {'field': {'warped': True}}, ], }, }, size=max_count, indices=['snaps'], sort='timestamp:desc') logger.debug(len(next_snaps)) if len(next_snaps) > 0: next_snap = next_snaps[0] unwarped_count = "%d" % len(next_snaps) if len(next_snaps) == max_count: unwarped_count += "+" if len(res) == 2: height, width = res else: height, width = 500, 500 # security loop elmts = filename.split(os.sep) for unsecure in ('.', '..'): if unsecure in elmts: return HTTPNotFound() data = {'snapshot': filename, 'original': get_original_path(filename), 'width': width, 'height': height, 'snap': current_snap, 'uuid': file_uuid, 'suggestions': suggestions, 'next_snap': next_snap, 'unwarped_count': unwarped_count} return _basic(request, data)