Source code for ibeis.web.appfuncs

# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function
import cStringIO as StringIO
import flask
import random
from ibeis.constants import TAU
from flask import request, current_app
from os.path import join, dirname, abspath  # NOQA
from datetime import datetime
from datetime import date
import base64
import jinja2
import utool as ut
import pynmea2
import simplejson as json
import numpy as np


DEFAULT_WEB_API_PORT = ut.get_argval('--port', type_=int, default=5000)
TARGET_WIDTH = 1200.0
PAGE_SIZE = 500
VALID_TURK_MODES = [
    ('turk_viewpoint', 'Viewpoint'),
    ('turk_quality', 'Quality'),
]



[docs]def resize_via_web_parameters(image): w_pix = request.args.get('resize_pix_w', request.form.get('resize_pix_w', None )) h_pix = request.args.get('resize_pix_h', request.form.get('resize_pix_h', None )) w_per = request.args.get('resize_per_w', request.form.get('resize_per_w', None )) h_per = request.args.get('resize_per_h', request.form.get('resize_per_h', None )) _pix = request.args.get('resize_prefer_pix', request.form.get('resize_prefer_pix', False)) _per = request.args.get('resize_prefer_per', request.form.get('resize_prefer_per', False)) args = (w_pix, h_pix, w_per, h_per, _pix, _per, ) print('CHECKING RESIZING WITH %r pix, %r pix, %r %%, %r %% [%r, %r]' % args) # Check for nothing if not (w_pix or h_pix or w_per or h_per): return image # Check for both pixels and images if (w_pix or h_pix) and (w_per or h_per): if _pix: w_per, h_per = None elif _per: w_pix, h_pix = None else: raise ValueError('Cannot resize using pixels and percentages, pick one') # Resize using percentages, transform to pixels if w_per: w_pix = float(w_per) * image.shape[1] if h_per: h_pix = float(h_per) * image.shape[0] # Perform resize return _resize(image, t_width=w_pix, t_height=h_pix)
[docs]def embed_image_html(imgBGR, target_width=TARGET_WIDTH): """ Creates an image embedded in HTML base64 format. """ import cv2 from PIL import Image if target_width is not None: imgBGR = _resize(imgBGR, target_width) imgRGB = cv2.cvtColor(imgBGR, cv2.COLOR_BGR2RGB) pil_img = Image.fromarray(imgRGB) string_buf = StringIO.StringIO() pil_img.save(string_buf, format='jpeg') data = string_buf.getvalue().encode('base64').replace('\n', '') return 'data:image/jpeg;base64,' + data
[docs]def check_valid_function_name(string): return all([ char.isalpha() or char == '_' or char.isalnum() for char in string])
[docs]def encode_refer_url(url): return base64.urlsafe_b64encode(str(url))
[docs]def decode_refer_url(encode): return base64.urlsafe_b64decode(str(encode))
[docs]def template(template_directory=None, template_filename=None, **kwargs): global_args = { 'NAVBAR': NavbarClass(), 'YEAR': date.today().year, 'URL': flask.request.url, 'REFER_SRC_STR': flask.request.url.replace(flask.request.url_root, ''), '__wrapper__' : True, } global_args['REFER_SRC_ENCODED'] = encode_refer_url(global_args['REFER_SRC_STR']) if 'refer' in flask.request.args.keys(): refer = flask.request.args['refer'] print('[web] REFER: %r' % (refer, )) global_args['REFER_DST_ENCODED'] = refer global_args['REFER_DST_STR'] = decode_refer_url(refer) if template_directory is None: template_directory = '' #template_directory = abspath(join(dirname(__file__), 'templates')) #template_directory = join(dirname(dirname(__file__))) if template_filename is None: template_filename = 'index' template_ = join(template_directory, template_filename + '.html') # Update global args with the template's args _global_args = dict(global_args) _global_args.update(kwargs) print('[appfuncs] template()') from ibeis.control import controller_inject app = controller_inject.get_flask_app() # flask hates windows apparently template_ = template_.replace('\\', '/') print('[appfuncs.template] * app.template_folder = %r' % (app.template_folder,)) print('[appfuncs.template] * template_directory = %r' % (template_directory,)) print('[appfuncs.template] * template_filename = %r' % (template_filename,)) print('[appfuncs.template] * template_ = %r' % (template_,)) try: ret = flask.render_template(template_, **_global_args) #ret = flask.render_template(full_template_fpath, **_global_args) except jinja2.exceptions.TemplateNotFound as ex: print('Error template not found') full_template_fpath = join(app.template_folder, template_) print('[appfuncs.template] * full_template_fpath = %r' % (full_template_fpath,)) ut.checkpath(full_template_fpath, verbose=True) ut.printex(ex, 'Template error in appfuncs', tb=True) raise except Exception as ex: ut.printex(ex, 'Error in appfuncs', tb=True) raise return ret
[docs]def send_csv_file(string, filename): response = flask.make_response(str(string)) response.headers['Content-Description'] = 'File Transfer' response.headers['Cache-Control'] = 'no-cache' response.headers['Content-Type'] = 'text/csv' response.headers['Content-Disposition'] = 'attachment; filename=%s' % filename response.headers['Content-Length'] = len(string) return response
[docs]def get_turk_annot_args(is_reviewed_func): """ Helper to return aids in an imageset or a group review """ ibs = current_app.ibs def _ensureid(_id): return None if _id == 'None' or _id == '' else int(_id) imgsetid = request.args.get('imgsetid', '') src_ag = request.args.get('src_ag', '') dst_ag = request.args.get('dst_ag', '') imgsetid = _ensureid(imgsetid) src_ag = _ensureid(src_ag) dst_ag = _ensureid(dst_ag) group_review_flag = src_ag is not None and dst_ag is not None if not group_review_flag: gid_list = ibs.get_valid_gids(imgsetid=imgsetid) aid_list = ut.flatten(ibs.get_image_aids(gid_list)) reviewed_list = is_reviewed_func(ibs, aid_list) else: src_gar_rowid_list = ibs.get_annotgroup_gar_rowids(src_ag) dst_gar_rowid_list = ibs.get_annotgroup_gar_rowids(dst_ag) src_aid_list = ibs.get_gar_aid(src_gar_rowid_list) dst_aid_list = ibs.get_gar_aid(dst_gar_rowid_list) aid_list = src_aid_list reviewed_list = [ src_aid in dst_aid_list for src_aid in src_aid_list ] try: progress = '%0.2f' % (100.0 * reviewed_list.count(True) / len(aid_list), ) except ZeroDivisionError: progress = '0.00' aid = request.args.get('aid', '') if len(aid) > 0: aid = int(aid) else: aid_list_ = ut.filterfalse_items(aid_list, reviewed_list) if len(aid_list_) == 0: aid = None else: if group_review_flag: aid = aid_list_[0] else: aid = random.choice(aid_list_) previous = request.args.get('previous', None) print('aid = %r' % (aid,)) #print(ut.dict_str(ibs.get_annot_info(aid))) print(ut.obj_str(ibs.get_annot_info(aid, default=True, nl=True))) return aid_list, reviewed_list, imgsetid, src_ag, dst_ag, progress, aid, previous
[docs]def movegroup_aid(ibs, aid, src_ag, dst_ag): gar_rowid_list = ibs.get_annot_gar_rowids(aid) annotgroup_rowid_list = ibs.get_gar_annotgroup_rowid(gar_rowid_list) src_index = annotgroup_rowid_list.index(src_ag) src_gar_rowid = gar_rowid_list[src_index] vals = (aid, src_ag, src_gar_rowid, dst_ag) print('Moving aid: %s from src_ag: %s (%s) to dst_ag: %s' % vals) # ibs.delete_gar([src_gar_rowid]) ibs.add_gar([dst_ag], [aid])
[docs]def default_species(ibs): # hack function dbname = ibs.get_dbname() if dbname == 'CHTA_Master': default_species = 'cheetah' elif dbname == 'ELPH_Master': default_species = 'elephant_savanna' elif dbname == 'GIR_Master': default_species = 'giraffe_reticulated' elif dbname == 'GZ_Master': default_species = 'zebra_grevys' elif dbname == 'LION_Master': default_species = 'lion' elif dbname == 'PZ_Master': default_species = 'zebra_plains' elif dbname == 'WD_Master': default_species = 'wild_dog' elif dbname == 'NNP_MasterGIRM': default_species = 'giraffe_masai' elif 'NNP_' in dbname: default_species = 'zebra_plains' elif 'GZC' in dbname: default_species = 'zebra_plains' else: default_species = None print('[web] DEFAULT SPECIES: %r' % (default_species)) return default_species
[docs]def imageset_image_processed(ibs, gid_list): images_reviewed = [ reviewed == 1 for reviewed in ibs.get_image_reviewed(gid_list) ] return images_reviewed
[docs]def imageset_annot_viewpoint_processed(ibs, aid_list): annots_reviewed = [ reviewed is not None for reviewed in ibs.get_annot_yaws(aid_list) ] return annots_reviewed
[docs]def imageset_annot_quality_processed(ibs, aid_list): annots_reviewed = [ reviewed is not None and reviewed is not -1 for reviewed in ibs.get_annot_qualities(aid_list) ] return annots_reviewed
[docs]def imageset_annot_additional_processed(ibs, aid_list, nid_list): sex_list = ibs.get_annot_sex(aid_list) age_list = ibs.get_annot_age_months_est(aid_list) annots_reviewed = [ (nid < 0) or (nid > 0 and sex >= 0 and -1 not in list(age) and list(age).count(None) < 2) for nid, sex, age in zip(nid_list, sex_list, age_list) ] return annots_reviewed
[docs]def convert_old_viewpoint_to_yaw(view_theta): """ we initially had viewpoint coordinates inverted Example: >>> import math >>> TAU = 2 * math.pi >>> old_viewpoint_labels = [ >>> ('left' , 0, 0.000 * TAU,), >>> ('frontleft' , 45, 0.125 * TAU,), >>> ('front' , 90, 0.250 * TAU,), >>> ('frontright' , 135, 0.375 * TAU,), >>> ('right' , 180, 0.500 * TAU,), >>> ('backright' , 225, 0.625 * TAU,), >>> ('back' , 270, 0.750 * TAU,), >>> ('backleft' , 315, 0.875 * TAU,), >>> ] >>> fmtstr = 'old %15r %.2f -> new %15r %.2f' >>> for lbl, theta, radians in old_viewpoint_labels: >>> print(fmtstr % (lbl, theta, lbl, convert_old_viewpoint_to_yaw(theta))) """ if view_theta is None: return None view_theta = ut.deg_to_rad(view_theta) yaw = (-view_theta + (TAU / 2)) % TAU return yaw
[docs]def convert_yaw_to_old_viewpoint(yaw): """ we initially had viewpoint coordinates inverted Example: >>> import math >>> TAU = 2 * math.pi >>> old_viewpoint_labels = [ >>> ('left' , 0, 0.000 * TAU,), >>> ('frontleft' , 45, 0.125 * TAU,), >>> ('front' , 90, 0.250 * TAU,), >>> ('frontright' , 135, 0.375 * TAU,), >>> ('right' , 180, 0.500 * TAU,), >>> ('backright' , 225, 0.625 * TAU,), >>> ('back' , 270, 0.750 * TAU,), >>> ('backleft' , 315, 0.875 * TAU,), >>> ] >>> fmtstr = 'original_theta %15r %.2f -> yaw %15r %.2f -> reconstructed_theta %15r %.2f' >>> for lbl, theta, radians in old_viewpoint_labels: >>> yaw = convert_old_viewpoint_to_yaw(theta) >>> reconstructed_theta = convert_yaw_to_old_viewpoint(yaw) >>> print(fmtstr % (lbl, theta, lbl, yaw, lbl, reconstructed_theta)) """ if yaw is None: return None view_theta = ((TAU / 2) - yaw) % TAU view_theta = ut.rad_to_deg(view_theta) return view_theta
[docs]def convert_nmea_to_json(nmea_str, filename, GMT_OFFSET=0): json_list = [] filename = filename.strip('.LOG').strip('N') year = 2000 + int(filename[0:2]) month = int(filename[2:4]) day = int(filename[4:6]) print(year, month, day) for line in nmea_str.split('\n'): line = line.strip() if '@' in line or 'GPRMC' in line or len(line) == 0: continue record = pynmea2.parse(line) dt = record.timestamp dt = datetime(year, month, day, dt.hour, dt.minute, dt.second) # Gather values posix = int(dt.strftime("%s")) posix += (60 * 60 * GMT_OFFSET) lat = float(record.latitude) lon = float(record.longitude) json_list.append({ 'time': posix, 'lat': lat, 'lon': lon, }) return json.dumps({ "track": json_list })
def _resize(image, t_width=None, t_height=None): import cv2 print('RESIZING WITH t_width = %r and t_height = %r' % (t_width, t_height, )) height, width = image.shape[:2] if t_width is None and t_height is None: return image elif t_width is not None and t_height is not None: pass elif t_width is None: t_width = (width / height) * float(t_height) elif t_height is None: t_height = (height / width) * float(t_width) t_width, t_height = float(t_width), float(t_height) t_width, t_height = int(np.around(t_width)), int(np.around(t_height)) assert t_width > 0 and t_height > 0, 'target size too small' assert t_width <= width * 100 and t_height <= height * 100, 'target size too large (capped at 10,000%)' # interpolation = cv2.INTER_LANCZOS4 interpolation = cv2.INTER_LINEAR return cv2.resize(image, (t_width, t_height), interpolation=interpolation)