Source code for ibeis.control.manual_image_funcs

# -*- coding: utf-8 -*-
"""
Functions for images and encoutners that will be injected into an
IBEISController instance.


CommandLine:
    # Autogenerate ImageSet Functions
    # key should be the table name
    # the write flag makes a file, but dont use that
    python -m ibeis.templates.template_generator --key image --onlyfn
    python -m ibeis.templates.template_generator --key image --fnfilt timedelta_posix --modfname manual_image_funcs  # NOQA
    python -m ibeis.templates.template_generator --key image --fnfilt location --modfname manual_image_funcs  # NOQA
    python -m ibeis.templates.template_generator --key image --fnfilt set_.*time --modfname manual_image_funcs  # NOQA

    image_timedelta_posix

"""
from __future__ import absolute_import, division, print_function
from ibeis import constants as const
from ibeis.control import accessor_decors, controller_inject
from ibeis.control.controller_inject import make_ibs_register_decorator
#from os.path import join, exists, abspath, normpath, isabs
from os.path import join, exists, isabs
import numpy as np
import utool as ut
import vtool as vt
from ibeis.web import routes_ajax
print, rrr, profile = ut.inject2(__name__, '[manual_image]')


DEBUG_THUMB = False

CLASS_INJECT_KEY, register_ibs_method = make_ibs_register_decorator(__name__)


register_api   = controller_inject.get_ibeis_flask_api(__name__)
register_route = controller_inject.get_ibeis_flask_route(__name__)


IMAGE_TIME_POSIX      = 'image_time_posix'
IMAGE_LOCATION_CODE   = 'image_location_code'
IMAGE_TIMEDELTA_POSIX = 'image_timedelta_posix'
PARTY_ROWID           = 'party_rowid'
CONTRIBUTOR_ROWID     = 'contributor_rowid'


@register_ibs_method
@accessor_decors.ider
def _get_all_gids(ibs):
    r"""
    alias

    Returns:
        list_ (list):  all unfiltered gids (image rowids)
    """
    all_gids = ibs._get_all_image_rowids()
    return all_gids


@register_ibs_method
def _get_all_image_rowids(ibs):
    r"""
    all_image_rowids <- image.get_all_rowids()

    Returns:
        list_ (list): unfiltered image_rowids

    TemplateInfo:
        Tider_all_rowids
        tbl = image

    CommandLine:
        python -m ibeis.control.manual_image_funcs --test-_get_all_image_rowids

    Example:
        >>> # ENABLE_DOCTEST
        >>> from ibeis.control.manual_image_funcs import *  # NOQA
        >>> ibs, config2_ = testdata_ibs()
        >>> all_image_rowids = ibs._get_all_image_rowids()
        >>> result = str(all_image_rowids)
        >>> print(result)
        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
    """
    all_image_rowids = ibs.db.get_all_rowids(const.IMAGE_TABLE)
    return all_image_rowids


@register_ibs_method
@accessor_decors.ider
@register_api('/api/image/', methods=['GET'])
[docs]def get_valid_gids(ibs, imgsetid=None, require_unixtime=False, require_gps=None, reviewed=None): r""" Args: ibs (IBEISController): ibeis controller object imgsetid (None): require_unixtime (bool): reviewed (None): Returns: list: gid_list CommandLine: python -m ibeis.control.manual_image_funcs --test-get_valid_gids RESTful: Method: GET URL: /api/image/ Example: >>> # ENABLE_DOCTEST >>> from ibeis.control.manual_image_funcs import * # NOQA >>> import ibeis >>> # build test data >>> ibs = ibeis.opendb('testdb1') >>> imgsetid = None >>> require_unixtime = False >>> reviewed = None >>> # execute function >>> gid_list = get_valid_gids(ibs, imgsetid, require_unixtime, reviewed) >>> # verify results >>> result = str(gid_list) >>> print(result) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] """ if imgsetid is None: gid_list = ibs._get_all_gids() else: assert not ut.isiterable(imgsetid) gid_list = ibs.get_imageset_gids(imgsetid) if require_unixtime: # Remove images without timestamps unixtime_list = ibs.get_image_unixtime(gid_list) isvalid_list = [unixtime != -1 for unixtime in unixtime_list] gid_list = ut.compress(gid_list, isvalid_list) if require_gps: isvalid_gps = [lat != -1 and lon != -1 for lat, lon in ibs.get_image_gps(gid_list)] gid_list = ut.compress(gid_list, isvalid_gps) if reviewed is not None: reviewed_list = ibs.get_image_reviewed(gid_list) isvalid_list = [reviewed == flag for flag in reviewed_list] gid_list = ut.compress(gid_list, isvalid_list) return gid_list
@register_ibs_method @register_api('/api/image/<gid>/', methods=['GET'])
[docs]def image_base64_api(gid=None, thumbnail=False, fresh=False, **kwargs): r""" Returns the base64 encoded image of image <gid> RESTful: Method: GET URL: /api/image/<gid>/ """ return routes_ajax.image_src(gid, thumbnail=thumbnail, fresh=fresh, **kwargs)
@register_ibs_method @accessor_decors.getter_1to1
[docs]def get_image_gid(ibs, gid_list, eager=True, nInput=None): """ self verifier CommandLine: python -m ibeis.control.manual_image_funcs --exec-get_image_gid Example: >>> # ENABLE_DOCTEST >>> from ibeis.control.IBEISControl import * # NOQA >>> import ibeis >>> ibs = ibeis.opendb('testdb1') >>> gid_list = ibs.get_valid_gids() + [None, -1, 10434320432] >>> gid_list_ = ibs.get_image_gid(gid_list) >>> assert [r is None for r in gid_list_[-3:]] >>> assert [r is not None for r in gid_list_[0:-3]] >>> print('gid_list_ = %r' % (gid_list_,)) """ id_iter = gid_list colnames = (IMAGE_ROWID,) gid_list = ibs.db.get(const.IMAGE_TABLE, colnames, id_iter, id_colname='rowid', eager=eager, nInput=nInput) return gid_list
@register_ibs_method @register_api('/api/image/gids_with_aids/', methods=['GET'])
[docs]def get_image_gids_with_aids(ibs, gid_list=None): if gid_list is None: gid_list = sorted(ibs.get_valid_gids()) aids_list = ibs.get_image_aids(gid_list) zipped = zip(gid_list, aids_list) combined_dict = { gid : aid_list for gid, aid_list in zipped } return combined_dict
@register_ibs_method @accessor_decors.ider @register_api('/api/image/valid_rowids/', methods=['GET'])
[docs]def get_valid_image_rowids(ibs, imgsetid=None, require_unixtime=False, reviewed=None): r""" alias RESTful: Method: GET URL: /api/image/valid_rowids/ """ return get_valid_gids(ibs, imgsetid, require_unixtime, reviewed)
@register_ibs_method @register_api('/api/image/num/', methods=['GET'])
[docs]def get_num_images(ibs, **kwargs): r""" Number of valid images RESTful: Method: GET URL: /api/image/num/ """ gid_list = ibs.get_valid_gids(**kwargs) return len(gid_list)
@register_ibs_method @accessor_decors.adder @accessor_decors.cache_invalidator(const.IMAGESET_TABLE, ['percent_imgs_reviewed_str']) @register_api('/api/image/path/', methods=['POST'])
[docs]def add_images(ibs, gpath_list, params_list=None, as_annots=False, auto_localize=None, sanitize=True, **kwargs): r""" Adds a list of image paths to the database. Initially we set the image_uri to exactely the given gpath. Later we change the uri, but keeping it the same here lets us process images asychronously. Args: gpath_list (list): list of image paths to add params_list (list): metadata list for corresponding images that can either be specified outright or can be parsed from the image data directly if None as_annots (bool): if True, an annotation is automatically added for the entire image auto_localize (bool): if None uses the default specified in ibs.cfg ensure (bool): check to see if the images exist on a \*NIX system. Defaults to True Returns: gid_list (list of rowids): gids are image rowids RESTful: Method: POST URL: /api/image/path Example0: >>> # ENABLE_DOCTEST >>> # Test returns None on fail to add >>> from ibeis.control.manual_image_funcs import * # NOQA >>> import ibeis >>> ibs = ibeis.opendb('testdb1') >>> gpath_list = ['doesnotexist.jpg'] >>> assert not ut.checkpath(gpath_list[0]) >>> gid_list = ibs.add_images(gpath_list) >>> assert len(gid_list) == len(gpath_list) >>> assert gid_list[0] is None Example1: >>> # ENABLE_DOCTSET >>> # test double add >>> from ibeis.control.manual_image_funcs import * # NOQA >>> import ibeis >>> ibs = ibeis.opendb('testdb1') >>> new_gpath_list = [ut.grab_test_imgpath('carl.jpg')] >>> new_gids1 = ibs.add_images(new_gpath_list, auto_localize=False) >>> new_gids2 = ibs.add_images(new_gpath_list, auto_localize=False) >>> #new_gids2 = ibs.add_images(new_gpath_list, auto_localize=True) >>> assert new_gids1 == new_gids2, 'should be the same' >>> new_gpath_list2 = ibs.get_image_paths(new_gids1) >>> assert new_gpath_list == new_gpath_list2, 'should not move when autolocalize is False' >>> # Clean things up >>> ibs.delete_images(new_gids1) """ from ibeis.algo.preproc import preproc_image from ibeis.other import ibsfuncs print('[ibs] add_images') print('[ibs] len(gpath_list) = %d' % len(gpath_list)) #print('[ibs] gpath_list = %r' % (gpath_list,)) # Processing an image might fail, yeilding a None instead of a tup if sanitize: gpath_list = ibsfuncs.ensure_unix_gpaths(gpath_list) if params_list is None: # Create param_iter params_list = list(preproc_image.add_images_params_gen(gpath_list)) # Error reporting print('\n'.join( [' ! Failed reading gpath=%r' % (gpath,) for (gpath, params_) in zip(gpath_list, params_list) if not params_])) # Add any unadded images colnames = ('image_uuid', 'image_uri', 'image_uri_original', 'image_original_name', 'image_ext', 'image_width', 'image_height', 'image_time_posix', 'image_gps_lat', 'image_gps_lon', 'image_orientation', 'image_note',) # <DEBUG> debug = False if debug: uuid_colx = colnames.index('image_uuid') uuid_list = [None if params_ is None else params_[uuid_colx] for params_ in params_list] gid_list_ = ibs.get_image_gids_from_uuid(uuid_list) valid_gids = ibs.get_valid_gids() valid_uuids = ibs.get_image_uuids(valid_gids) print('[preadd] uuid / gid_ = ' + ut.indentjoin(zip(uuid_list, gid_list_))) print('[preadd] valid uuid / gid = ' + ut.indentjoin(zip(valid_uuids, valid_gids))) # </DEBUG> # Execute SQL Add from distutils.version import LooseVersion if LooseVersion(ibs.db.get_db_version()) >= LooseVersion('1.3.4'): colnames = colnames + ('image_original_path', 'image_location_code') params_list = [tuple(params) + (gpath, ibs.cfg.other_cfg.location_for_names) if params is not None else None for params, gpath in zip(params_list, gpath_list)] gid_list = ibs.db.add_cleanly(const.IMAGE_TABLE, colnames, params_list, ibs.get_image_gids_from_uuid) none_idxs = ut.where(ut.flag_None_items(gid_list)) ut.take(params_list, none_idxs) if ut.duplicates_exist(gid_list): gpath_list = ibs.get_image_paths(gid_list) guuid_list = ibs.get_image_uuids(gid_list) gext_list = ibs.get_image_exts(gid_list) if ut.VERBOSE: ut.debug_duplicate_items(gid_list, gpath_list, guuid_list, gext_list) if ut.VERBOSE: uuid_list = [None if params_ is None else params_[0] for params_ in params_list] gid_list_ = ibs.get_image_gids_from_uuid(uuid_list) valid_gids = ibs.get_valid_gids() valid_uuids = ibs.get_image_uuids(valid_gids) print('[postadd] uuid / gid_ = ' + ut.indentjoin(zip(uuid_list, gid_list_))) print('[postadd] uuid / gid = ' + ut.indentjoin(zip(uuid_list, gid_list))) print('[postadd] valid uuid / gid = ' + ut.indentjoin(zip(valid_uuids, valid_gids))) #ibs.cfg.other_cfg.ensure_attr('auto_localize', True) if auto_localize is None: # grab value from config auto_localize = ibs.cfg.other_cfg.auto_localize if auto_localize: # Move to ibeis database local cache ibs.localize_images(ut.filter_Nones(gid_list)) if as_annots: # Add succesfull imports as annotations notnone_list = [gid is None for gid in gid_list] gid_list_ = ut.compress(gid_list, notnone_list) aid_list = ibs.use_images_as_annotations(gid_list) print('[ibs] added %d annotations' % (len(aid_list),)) return gid_list
@register_ibs_method
[docs]def localize_images(ibs, gid_list_=None): r""" Moves the images into the ibeis image cache. Images are renamed to img_uuid.ext Args: ibs (IBEISController): ibeis controller object gid_list_ (list): CommandLine: python -m ibeis.control.manual_image_funcs --test-localize_images Example: >>> # ENABLE_DOCTEST >>> from ibeis.control.manual_image_funcs import * # NOQA >>> import ibeis >>> # build test data >>> ibs = ibeis.opendb('testdb1') >>> gpath_list = [ut.unixpath(ut.grab_test_imgpath('carl.jpg'))] >>> gid_list_ = ibs.add_images(gpath_list, auto_localize=False) >>> gpath_list2 = ibs.get_image_paths(gid_list_) >>> ut.assert_eq(gpath_list, gpath_list2, 'should not move when autolocalize is False') >>> # execute function >>> result = localize_images(ibs, gid_list_) >>> gpath_list3 = ibs.get_image_paths(gid_list_) >>> assert gpath_list3 != gpath_list2, 'should now be different gpath_list3=%r' % (gpath_list3,) >>> gpath3 = gpath_list3[0] >>> rel_gpath3 = ut.relpath_unix(gpath3, ibs.get_workdir()) >>> result = rel_gpath3 >>> print(result) >>> # Clean things up >>> ibs.delete_images(gid_list_) testdb1/_ibsdb/images/f498fa6f-6b24-b4fa-7932-2612144fedd5.jpg Ignore: ibs.vd() """ #from os.path import isabs from six.moves import urllib if gid_list_ is None: print('WARNING: you are localizing all gids') gid_list_ = ibs.get_valid_gids() isnone_list = [gid is None for gid in gid_list_] gid_list = ut.unique_ordered(ut.filterfalse_items(gid_list_, isnone_list)) #gpath_list = ibs.get_image_paths(gid_list) uri_list = ibs.get_image_uris(gid_list) url_protos = ['https://', 'http://'] s3_proto = ['s3://'] valid_protos = s3_proto + url_protos def isproto(uri, valid_protos): return any(uri.startswith(proto) for proto in valid_protos) def islocal(uri): return not (isabs(uri) and isproto(uri, valid_protos)) abs_uri_list = [uri if islocal(uri) else join(ibs.imgdir, uri) for uri in uri_list] guuid_list = ibs.get_image_uuids(gid_list) gext_list = ibs.get_image_exts(gid_list) # Build list of image names based on uuid in the ibeis imgdir guuid_strs = (str(guuid) for guuid in guuid_list) loc_gname_list = [guuid + ext for (guuid, ext) in zip(guuid_strs, gext_list)] loc_gpath_list = [join(ibs.imgdir, gname) for gname in loc_gname_list] # Copy any s3/http images first for uri, loc_gpath in zip(uri_list, loc_gpath_list): if isproto(uri, s3_proto): s3_dict = ut.s3_str_decode_to_dict(uri) ut.grab_s3_contents(loc_gpath, **s3_dict) if isproto(uri, url_protos): urllib.request.urlretrieve(uri, filename=loc_gpath) # Copy images to local directory #needs_copy_flags = [normpath(abspath(gp)) != normpath(abspath(lgp)) # for gp, lgp in zip(abs_uri_list, loc_gpath_list)] needs_copy_flags = [not exists(gpath) for gpath in loc_gpath_list] # --- loc_gpath_list_ = ut.compress(loc_gpath_list, needs_copy_flags) #loc_gname_list_ = ut.compress(loc_gname_list, needs_copy_flags) gpath_list_ = ut.compress(abs_uri_list, needs_copy_flags) gid_list_ = ut.compress(gid_list, needs_copy_flags) ut.copy_list(gpath_list_, loc_gpath_list_, lbl='Localizing Images: ') # Update database uris #ibs.set_image_uris(gid_list_, loc_gname_list_) ibs.set_image_uris(gid_list, loc_gname_list) assert all(map(exists, loc_gpath_list)), 'not all images copied' # SETTERS::IMAGE
@register_ibs_method @accessor_decors.setter @register_api('/api/image/uris/', methods=['PUT'])
[docs]def set_image_uris(ibs, gid_list, new_gpath_list): r""" Sets the image URIs to a new local path. This is used when localizing or unlocalizing images. An absolute path can either be on this machine or on the cloud A relative path is relative to the ibeis image cache on this machine. RESTful: Method: PUT URL: /api/image/uris/ """ id_iter = ((gid,) for gid in gid_list) val_list = ((new_gpath,) for new_gpath in new_gpath_list) ibs.db.set(const.IMAGE_TABLE, ('image_uri',), val_list, id_iter)
@register_ibs_method @accessor_decors.setter @register_api('/api/image/uris_original/', methods=['PUT'])
[docs]def set_image_uris_original(ibs, gid_list, new_gpath_list, overwrite=False): r""" Sets the (original) image URIs to a new local path. Args: overwrite (bool): If overwrite, replace the information in the database. This ensures that original uris cannot be accidentally overwritten. Defaults to False. RESTful: Method: PUT URL: /api/image/uris_original/ """ def _invalid(uri_original): return current is None or len(current) == 0 current_uri_original_list = ibs.get_image_uris_original(gid_list) new_gpath_list_ = [ new if _invalid(current) or overwrite else current for current, new in zip(current_uri_original_list, new_gpath_list) ] id_iter = ((gid,) for gid in gid_list) val_list = ((new_gpath,) for new_gpath in new_gpath_list_) ibs.db.set(const.IMAGE_TABLE, ('image_uri_original',), val_list, id_iter)
@register_ibs_method @accessor_decors.setter @register_api('/api/image/contributor_rowid/', methods=['PUT'])
[docs]def set_image_contributor_rowid(ibs, gid_list, contributor_rowid_list, **kwargs): r""" Sets the image contributor rowid RESTful: Method: PUT URL: /api/image/contributor_rowid/ """ id_iter = ((gid,) for gid in gid_list) val_list = ((contrib_rowid,) for contrib_rowid in contributor_rowid_list) ibs.db.set(const.IMAGE_TABLE, ('contributor_rowid',), val_list, id_iter, **kwargs)
@register_ibs_method @accessor_decors.setter @accessor_decors.cache_invalidator(const.IMAGESET_TABLE, ['percent_imgs_reviewed_str']) @register_api('/api/image/reviewed/', methods=['PUT'])
[docs]def set_image_reviewed(ibs, gid_list, reviewed_list): r""" Sets the image all instances found bit RESTful: Method: PUT URL: /api/image/reviewed/ """ id_iter = ((gid,) for gid in gid_list) val_list = ((reviewed,) for reviewed in reviewed_list) ibs.db.set(const.IMAGE_TABLE, ('image_toggle_reviewed',), val_list, id_iter)
@register_ibs_method @accessor_decors.setter @register_api('/api/image/enabled/', methods=['PUT'])
[docs]def set_image_enabled(ibs, gid_list, enabled_list): r""" Sets the image all instances found bit RESTful: Method: PUT URL: /api/image/enabled/ """ id_iter = ((gid,) for gid in gid_list) val_list = ((enabled,) for enabled in enabled_list) ibs.db.set(const.IMAGE_TABLE, ('image_toggle_enabled',), val_list, id_iter)
@register_ibs_method @accessor_decors.setter @register_api('/api/image/notes/', methods=['PUT'])
[docs]def set_image_notes(ibs, gid_list, notes_list): r""" Sets the image all instances found bit RESTful: Method: PUT URL: /api/image/notes/ """ id_iter = ((gid,) for gid in gid_list) val_list = ((notes,) for notes in notes_list) ibs.db.set(const.IMAGE_TABLE, ('image_note',), val_list, id_iter)
@register_ibs_method @accessor_decors.setter @register_api('/api/image/unixtime/', methods=['PUT'])
[docs]def set_image_unixtime(ibs, gid_list, unixtime_list, duplicate_behavior='error'): r""" Sets the image unixtime (does not modify exif yet) alias for set_image_time_posix RESTful: Method: PUT URL: /api/image/unixtime/ """ id_iter = ((gid,) for gid in gid_list) val_list = ((unixtime,) for unixtime in unixtime_list) ibs.db.set(const.IMAGE_TABLE, (IMAGE_TIME_POSIX,), val_list, id_iter, duplicate_behavior=duplicate_behavior)
@register_ibs_method @register_api('/api/image/time_posix/', methods=['PUT'])
[docs]def set_image_time_posix(ibs, image_rowid_list, image_time_posix_list, duplicate_behavior='error'): r""" image_time_posix_list -> image.image_time_posix[image_rowid_list] SeeAlso: set_image_unixtime Args: image_rowid_list image_time_posix_list TemplateInfo: Tsetter_native_column tbl = image col = image_time_posix RESTful: Method: PUT URL: /api/image/time_posix/ """ id_iter = image_rowid_list colnames = (IMAGE_TIME_POSIX,) ibs.db.set(const.IMAGE_TABLE, colnames, image_time_posix_list, id_iter, duplicate_behavior=duplicate_behavior)
@register_ibs_method @accessor_decors.setter @register_api('/api/image/imagesettext/', methods=['PUT'])
[docs]def set_image_imagesettext(ibs, gid_list, imagesettext_list): r""" Sets the encoutertext of each image RESTful: Method: PUT URL: /api/image/imagesettext/ """ # FIXME: Slow and weird if ut.VERBOSE: print('[ibs] setting %r image imageset ids (from text)' % len(gid_list)) imgsetid_list = ibs.add_imagesets(imagesettext_list) ibs.set_image_imgsetids(gid_list, imgsetid_list)
@register_ibs_method @accessor_decors.setter @register_api('/api/image/imgsetids/', methods=['PUT'])
[docs]def set_image_imgsetids(ibs, gid_list, imgsetid_list): r""" Sets the encoutertext of each image RESTful: Method: PUT URL: /api/image/imgsetids/ """ if ut.VERBOSE: print('[ibs] setting %r image imageset ids' % len(gid_list)) gsgrid_list = ibs.add_image_relationship(gid_list, imgsetid_list) del gsgrid_list
@register_ibs_method @accessor_decors.setter @register_api('/api/image/gps/', methods=['PUT'])
[docs]def set_image_gps(ibs, gid_list, gps_list=None, lat_list=None, lon_list=None): r""" see get_image_gps for how the gps_list should look. lat and lon should be given in degrees RESTful: Method: PUT URL: /api/image/gps/ """ if gps_list is not None: assert lat_list is None assert lon_list is None lat_list = [tup[0] for tup in gps_list] lon_list = [tup[1] for tup in gps_list] colnames = ('image_gps_lat', 'image_gps_lon',) val_list = zip(lat_list, lon_list) id_iter = ((gid,) for gid in gid_list) ibs.db.set(const.IMAGE_TABLE, colnames, val_list, id_iter)
@register_ibs_method @accessor_decors.setter def _set_image_sizes(ibs, gid_list, width_list, height_list): colnames = ('image_width', 'image_height',) val_list = zip(width_list, height_list) id_iter = ((gid,) for gid in gid_list) ibs.db.set(const.IMAGE_TABLE, colnames, val_list, id_iter) @register_ibs_method @accessor_decors.setter @register_api('/api/image/orientation/', methods=['PUT'])
[docs]def set_image_orientation(ibs, gid_list, orientation_list): r""" RESTful: Method: PUT URL: /api/image/orientation/ """ # # FIXME: is this correct? # current_list = ibs.get_image_orientation(gid_list) # zipped = zip(gid_list, current_list, orientation_list) # for gid, current, orientation in zipped: # if current in [1] and orientation in [6, 8]: # # Fix orientation # width, height = ibs.get_image_sizes(gid) # ibs._set_image_sizes(gid, height, width) # aid_list = ibs.get_image_aids(gid) # bbox_list = ibs.get_annot_bboxes(aid_list) # bbox_list_ = ibs.fix_horizontal_bounding_boxes_to_orient(gid, bbox_list) # ibs.set_annot_bboxes(aid_list, bbox_list_) colnames = ('image_orientation',) val_list = ((orientation,) for orientation in orientation_list) id_iter = ((gid,) for gid in gid_list) ibs.db.set(const.IMAGE_TABLE, colnames, val_list, id_iter) # ibs.depc_image.notify_root_changed(gid_list, 'img') # # GETTERS::IMAGE_TABLE
@register_ibs_method @accessor_decors.getter_1to1
[docs]def get_images(ibs, gid_list, force_orient=False, **kwargs): r""" Returns: list_ (list): a list of images in numpy matrix form by gid Args: ibs (IBEISController): ibeis controller object gid_list (list): Returns: list: image_list CommandLine: python -m ibeis.control.manual_image_funcs --test-get_images RESTful: Returns the base64 encoded image of image <gid> # Documented and routed in ibeis.web app.py Method: GET URL: /api/image/<gid> Example: >>> # ENABLE_DOCTEST >>> from ibeis.control.manual_image_funcs import * # NOQA >>> import ibeis >>> # build test data >>> ibs = ibeis.opendb('testdb1') >>> gid_list = ibs.get_valid_gids()[0:1] >>> # execute function >>> image_list = get_images(ibs, gid_list) >>> # verify results >>> result = str(image_list[0].shape) >>> print(result) (715, 1047, 3) """ orient_list = ibs.get_image_orientation(gid_list) orient_list = [orient if force_orient else False for orient in orient_list] gpath_list = ibs.get_image_paths(gid_list) zipped = zip(gpath_list, orient_list) image_list = [vt.imread(gpath, orient=orient) for gpath, orient in zipped] return image_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/thumbtup/', methods=['GET'])
[docs]def get_image_thumbtup(ibs, gid_list, **kwargs): r""" Returns: list: thumbtup_list - [(thumb_path, img_path, imgsize, bboxes, thetas)] RESTful: Method: GET URL: /api/image/thumbtup/ """ if DEBUG_THUMB: print('{TUPPLE} get thumbtup kwargs = %r' % (kwargs,)) # print('gid_list = %r' % (gid_list,)) aids_list = ibs.get_image_aids(gid_list) bboxes_list = ibs.unflat_map(ibs.get_annot_bboxes, aids_list) thetas_list = ibs.unflat_map(ibs.get_annot_thetas, aids_list) thumb_gpaths = ibs.get_image_thumbpath(gid_list, **kwargs) image_paths = ibs.get_image_paths(gid_list) gsize_list = ibs.get_image_sizes(gid_list) thumbtup_list = [ (thumb_path, img_path, img_size, bboxes, thetas) for thumb_path, img_path, img_size, bboxes, thetas in zip(thumb_gpaths, image_paths, gsize_list, bboxes_list, thetas_list) ] # if DEBUG_THUMB: # print('{TUPPLE} get thumbtup_list = %r' % (thumbtup_list,)) return thumbtup_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/thumbpath/', methods=['GET'])
[docs]def get_image_thumbpath(ibs, gid_list, ensure_paths=False, **config): r""" Returns: list_ (list): the thumbnail path of each gid RESTful: Method: GET URL: /api/image/thumbpath/ """ if DEBUG_THUMB: print('[GET} get_image_thumbpath for %d gids' % (len(gid_list))) print('[GET} get thumbtup config = %r' % (config,)) print('[GET} get thumbtup ensure_paths = %r' % (ensure_paths,)) #raise Exception("FOOBAR") depc = ibs.depc_image # Do not force computation just ask where the thumbs will go # This will allow the frontend to know where to read the images when they # are ready. They should be computed in the background. # HACK: this is hacked into the depcache to force it to work # It is not gaurneteed that it will ever work # FIXME: I think Qt will end up computing these thumbnails and writing them # to where the depcache expects them. I think the depcache will then # override them but this may cause unexpected results. # FIXME: Thumbnails may have annotations drawn on them! This is not # represented anywhere in the depcache. thumbpath_list = depc.get('thumbnails', gid_list, 'img', config=config, read_extern=False, ensure=ensure_paths, hack_paths=not ensure_paths) #except dtool.ExternalStorageException: # # TODO; this check might go in dtool itself # thumbpath_list = depc.get('thumbnails', gid_list, 'img', config=config, # read_extern=False) if DEBUG_THUMB: print('[GET} thumbpath_list = %r' % (thumbpath_list,)) return thumbpath_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/uuids/', methods=['GET'])
[docs]def get_image_uuids(ibs, gid_list): r""" Returns: list_ (list): a list of image uuids by gid Args: ibs (IBEISController): ibeis controller object gid_list (list): Returns: list: image_uuid_list CommandLine: python -m ibeis.control.manual_image_funcs --test-get_image_uuids RESTful: Method: GET URL: /api/image/uuids/ Example: >>> # ENABLE_DOCTEST >>> from ibeis.control.manual_image_funcs import * # NOQA >>> import ibeis >>> # build test data >>> ibs = ibeis.opendb('testdb1') >>> gid_list = ibs.get_valid_gids() >>> # execute function >>> image_uuid_list = ibs.get_image_uuids(gid_list) >>> # verify results >>> result = ut.list_str(image_uuid_list) >>> print(result) [ UUID('66ec193a-1619-b3b6-216d-1784b4833b61'), UUID('d8903434-942f-e0f5-d6c2-0dcbe3137bf7'), UUID('b73b72f4-4acb-c445-e72c-05ce02719d3d'), UUID('0cd05978-3d83-b2ee-2ac9-798dd571c3b3'), UUID('0a9bc03d-a75e-8d14-0153-e2949502aba7'), UUID('2deeff06-5546-c752-15dc-2bd0fdb1198a'), UUID('a9b70278-a936-c1dd-8a3b-bc1e9a998bf0'), UUID('42fdad98-369a-2cbc-67b1-983d6d6a3a60'), UUID('c459d381-fd74-1d99-6215-e42e3f432ea9'), UUID('33fd9813-3a2b-774b-3fcc-4360d1ae151b'), UUID('97e8ea74-873f-2092-b372-f928a7be30fa'), UUID('588bc218-83a5-d400-21aa-d499832632b0'), UUID('163a890c-36f2-981e-3529-c552b6d668a3'), ] """ image_uuid_list = ibs.db.get(const.IMAGE_TABLE, ('image_uuid',), gid_list) return image_uuid_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/uuids/valid/', methods=['GET'])
[docs]def get_valid_image_uuids(ibs): r""" Returns: list_ (list): a list of image uuids for all valid gids Args: ibs (IBEISController): ibeis controller object Returns: list: image_uuid_list CommandLine: python -m ibeis.control.manual_image_funcs --test-get_image_uuids RESTful: Method: GET URL: /api/image/uuids/valid/ """ gid_list = ibs.get_valid_gids() image_uuid_list = ibs.get_image_uuids(gid_list) return image_uuid_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/contributor_rowid/', methods=['GET'])
[docs]def get_image_contributor_rowid(ibs, image_rowid_list, eager=True, nInput=None): r""" contributor_rowid_list <- image.contributor_rowid[image_rowid_list] gets data from the "native" column "contributor_rowid" in the "image" table Args: image_rowid_list (list): Returns: list: contributor_rowid_list - list of image contributor rowids by gid TemplateInfo: Tgetter_table_column col = contributor_rowid tbl = image RESTful: Method: GET URL: /api/image/contributor_rowid/ Example: >>> # ENABLE_DOCTEST >>> from ibeis.control.manual_image_funcs import * # NOQA >>> ibs, config2_ = testdata_ibs() >>> image_rowid_list = ibs._get_all_image_rowids() >>> eager = True >>> contributor_rowid_list = ibs.get_image_contributor_rowid(image_rowid_list, eager=eager) >>> assert len(image_rowid_list) == len(contributor_rowid_list) """ id_iter = image_rowid_list colnames = (CONTRIBUTOR_ROWID,) contributor_rowid_list = ibs.db.get( const.IMAGE_TABLE, colnames, id_iter, id_colname='rowid', eager=eager, nInput=nInput) return contributor_rowid_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/exts/', methods=['GET'])
[docs]def get_image_exts(ibs, gid_list): r""" Returns: list_ (list): a list of image uuids by gid RESTful: Method: GET URL: /api/image/exts/ """ image_uuid_list = ibs.db.get(const.IMAGE_TABLE, ('image_ext',), gid_list) return image_uuid_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/uris/', methods=['GET'])
[docs]def get_image_uris(ibs, gid_list): r""" Returns: list_ (list): a list of image uris relative to the image dir by gid RESTful: Method: GET URL: /api/image/uris/ """ uri_list = ibs.db.get(const.IMAGE_TABLE, ('image_uri',), gid_list) return uri_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/uris_original/', methods=['GET'])
[docs]def get_image_uris_original(ibs, gid_list): r""" Returns: list_ (list): a list of (original) image uris relative to the image dir by gid RESTful: Method: GET URL: /api/image/uris_original/ """ uri_list = ibs.db.get(const.IMAGE_TABLE, ('image_uri_original',), gid_list) return uri_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/gids_from_uuid/', methods=['GET'])
[docs]def get_image_gids_from_uuid(ibs, uuid_list): r""" Returns: list_ (list): a list of original image names RESTful: Method: GET URL: /api/image/gids_from_uuid/ """ # FIXME: MAKE SQL-METHOD FOR NON-ROWID GETTERS gid_list = ibs.db.get(const.IMAGE_TABLE, ('image_rowid',), uuid_list, id_colname='image_uuid') return gid_list #get_image_rowid_from_uuid = get_image_gids_from_uuid
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/missing_uuid/', methods=['GET'])
[docs]def get_image_missing_uuid(ibs, uuid_list): r""" Returns: list_ (list): a list of missing image uuids RESTful: Method: GET URL: /api/image/missing_uuid/ """ gid_list = ibs.get_image_gids_from_uuid(uuid_list) zipped = zip(gid_list, uuid_list) missing_uuid_list = [ uuid for gid, uuid in zipped if gid is None ] return missing_uuid_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/paths/', methods=['GET'])
[docs]def get_image_paths(ibs, gid_list): r""" Args: ibs (IBEISController): ibeis controller object gid_list (list): a list of image absolute paths to img_dir Returns: list: gpath_list CommandLine: python -m ibeis.control.manual_image_funcs --test-get_image_paths RESTful: Method: GET URL: /api/image/paths/ Example: >>> # ENABLE_DOCTEST >>> from ibeis.control.manual_image_funcs import * # NOQA >>> import ibeis >>> # build test data >>> ibs = ibeis.opendb('testdb1') >>> #gid_list = ibs.get_valid_gids() >>> # execute function >>> #gpath_list = get_image_paths(ibs, gid_list) >>> new_gpath = ut.unixpath(ut.grab_test_imgpath('carl.jpg')) >>> gid_list = ibs.add_images([new_gpath], auto_localize=False) >>> new_gpath_list = get_image_paths(ibs, gid_list) >>> # verify results >>> ut.assert_eq(new_gpath, new_gpath_list[0]) >>> result = str(new_gpath_list) >>> # clean up the database! >>> ibs.delete_images(gid_list) >>> # ibs.delete_images(new_gids) >>> print(result) """ #ut.assert_all_not_None(gid_list, 'gid_list', key_list=['gid_list']) uri_list = ibs.get_image_uris(gid_list) # Images should never have null uris # If the uri is not absolute then it is infered to be relative to ibs.imgdir #ut.assert_all_not_None(uri_list, 'uri_list', key_list=['uri_list', 'gid_list']) # Note: join does not prepend anything if the uri is absolute gpath_list = [None if uri is None else join(ibs.imgdir, uri) for uri in uri_list] return gpath_list # TODO make this actually return a uri format #get_image_absolute_uri = get_image_paths
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/detectpaths/', methods=['GET'])
[docs]def get_image_detectpaths(ibs, gid_list): r""" Returns: list_ (list): a list of image paths resized to a constant area for detection RESTful: Method: GET URL: /api/image/detectpaths/ """ import dtool depc = ibs.depc_image config = { 'thumbsize': ibs.cfg.detect_cfg.detectimg_sqrt_area, 'force_serial': True, } try: thumbpath_list = depc.get('thumbnails', gid_list, 'img', config=config, read_extern=False) except dtool.ExternalStorageException: # TODO; this check might go in dtool itself thumbpath_list = depc.get('thumbnails', gid_list, 'img', config=config, read_extern=False) print(thumbpath_list) return thumbpath_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/gnames/', methods=['GET'])
[docs]def get_image_gnames(ibs, gid_list): r""" Args: gid_list (list): Returns: list: gname_list - a list of original image names CommandLine: python -m ibeis.control.manual_image_funcs --test-get_image_gnames RESTful: Method: GET URL: /api/image/gnames/ Example: >>> # ENABLE_DOCTEST >>> from ibeis.control.manual_image_funcs import * # NOQA >>> import ibeis >>> # build test data >>> ibs = ibeis.opendb('testdb1') >>> gid_list = ibs.get_valid_gids() >>> # execute function >>> gname_list = get_image_gnames(ibs, gid_list) >>> # verify results >>> result = ut.list_str(gname_list) >>> print(result) [ 'easy1.JPG', 'easy2.JPG', 'easy3.JPG', 'hard1.JPG', 'hard2.JPG', 'hard3.JPG', 'jeff.png', 'lena.jpg', 'occl1.JPG', 'occl2.JPG', 'polar1.jpg', 'polar2.jpg', 'zebra.jpg', ] """ gname_list = ibs.db.get(const.IMAGE_TABLE, ('image_original_name',), gid_list) return gname_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/sizes/', methods=['GET'])
[docs]def get_image_sizes(ibs, gid_list): r""" Returns: list_ (list): a list of (width, height) tuples RESTful: Method: GET URL: /api/image/sizes/ """ gsize_list = ibs.db.get(const.IMAGE_TABLE, ('image_width', 'image_height'), gid_list) return gsize_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/widths/', methods=['GET'])
[docs]def get_image_widths(ibs, gid_list): r""" Returns: list_ (list): a list of (width, height) tuples RESTful: Method: GET URL: /api/image/widths/ """ gwidth_list = ibs.db.get(const.IMAGE_TABLE, ('image_width',), gid_list) return gwidth_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/heights/', methods=['GET'])
[docs]def get_image_heights(ibs, gid_list): r""" Returns: list_ (list): a list of (width, height) tuples RESTful: Method: GET URL: /api/image/heights/ """ gheight_list = ibs.db.get(const.IMAGE_TABLE, ('image_height',), gid_list) return gheight_list
@register_ibs_method @ut.accepts_numpy @accessor_decors.getter_1to1 @register_api('/api/image/unixtime/', methods=['GET'])
[docs]def get_image_unixtime(ibs, gid_list): r""" Returns: list_ (list): a list of times that the images were taken by gid. Returns: list_ (list): -1 if no timedata exists for a given gid RESTful: Method: GET URL: /api/image/unixtime/ """ return ibs.db.get(const.IMAGE_TABLE, ('image_time_posix',), gid_list)
@register_ibs_method @accessor_decors.getter_1to1
[docs]def get_image_datetime(ibs, gid_list): unixtime_list = ibs.get_image_unixtime(gid_list) datetime_list = list(map(ut.unixtime_to_datetimestr, unixtime_list)) return datetime_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/gps/', methods=['GET'])
[docs]def get_image_gps(ibs, gid_list): r""" Returns: gps_list (list): -1 if no timedata exists for a given gid RESTful: Method: GET URL: /api/image/gps/ """ gps_list = ibs.db.get(const.IMAGE_TABLE, ('image_gps_lat', 'image_gps_lon'), gid_list) return gps_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/lat/', methods=['GET'])
[docs]def get_image_lat(ibs, gid_list): r""" RESTful: Method: GET URL: /api/image/lat/ """ lat_list = ibs.db.get(const.IMAGE_TABLE, ('image_gps_lat',), gid_list) return lat_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/lon/', methods=['GET'])
[docs]def get_image_lon(ibs, gid_list): r""" RESTful: Method: GET URL: /api/image/lon/ """ lon_list = ibs.db.get(const.IMAGE_TABLE, ('image_gps_lon',), gid_list) return lon_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/orientation/', methods=['GET'])
[docs]def get_image_orientation(ibs, gid_list): r""" RESTful: Method: GET URL: /api/image/orientation/ """ orient_list = ibs.db.get(const.IMAGE_TABLE, ('image_orientation',), gid_list) return orient_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/orientation_str/', methods=['GET'])
[docs]def get_image_orientation_str(ibs, gid_list): r""" RESTful: Method: GET URL: /api/image/orientation_str/ """ from vtool.exif import ORIENTATION_DICT orient_list = ibs.get_image_orientation(gid_list) orient_str = [ ORIENTATION_DICT[orient] for orient in orient_list ] return orient_str
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/enabled/', methods=['GET'])
[docs]def get_image_enabled(ibs, gid_list): r""" Returns: list_ (list): "Image Enabled" flag, true if the image is enabled RESTful: Method: GET URL: /api/image/enabled/ """ enabled_list = ibs.db.get(const.IMAGE_TABLE, ('image_toggle_enabled',), gid_list) return enabled_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/reviewed/', methods=['GET'])
[docs]def get_image_reviewed(ibs, gid_list): r""" Returns: list_ (list): "All Instances Found" flag, true if all objects of interest (animals) have an ANNOTATION in the image RESTful: Method: GET URL: /api/image/reviewed/ """ reviewed_list = ibs.db.get(const.IMAGE_TABLE, ('image_toggle_reviewed',), gid_list) return reviewed_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/detect_confidence/', methods=['GET'])
[docs]def get_image_detect_confidence(ibs, gid_list): r""" Returns: list_ (list): image detection confidence as the max of ANNOTATION confidences RESTful: Method: GET URL: /api/image/detect_confidence/ """ aids_list = ibs.get_image_aids(gid_list) confs_list = ibs.unflat_map(ibs.get_annot_detect_confidence, aids_list) maxconf_list = [max(confs) if len(confs) > 0 else -1 for confs in confs_list] return maxconf_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/notes/', methods=['GET'])
[docs]def get_image_notes(ibs, gid_list): r""" Returns: list_ (list): image notes RESTful: Method: GET URL: /api/image/notes/ """ notes_list = ibs.db.get(const.IMAGE_TABLE, ('image_note',), gid_list) return notes_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/nids/', methods=['GET'])
[docs]def get_image_nids(ibs, gid_list): r""" Args: ibs (IBEISController): ibeis controller object gid_list (list): Returns: list: nids_list - the name ids associated with an image id CommandLine: python -m ibeis.control.manual_image_funcs --test-get_image_nids RESTful: Method: GET URL: /api/image/nids/ Example: >>> # DISABLE_DOCTEST >>> from ibeis.control.manual_image_funcs import * # NOQA >>> import ibeis >>> # build test data >>> ibs = ibeis.opendb('testdb1') >>> gid_list = ibs.get_valid_gids() >>> # execute function >>> nids_list = ibs.get_image_nids(gid_list) >>> # verify results >>> result = str(nids_list) >>> print(result) """ aids_list = ibs.get_image_aids(gid_list) nids_list = ibs.unflat_map(ibs.get_annot_name_rowids, aids_list) return nids_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/species_rowids/', methods=['GET'])
[docs]def get_image_species_rowids(ibs, gid_list): r""" Returns: list_ (list): the name ids associated with an image id RESTful: Method: GET URL: /api/image/species_rowids/ """ aids_list = ibs.get_image_aids(gid_list) species_rowid_list = ibs.get_annot_species_rowids(aids_list) return species_rowid_list
@register_ibs_method @accessor_decors.getter_1toM @register_api('/api/image/imgsetids/', methods=['GET'])
[docs]def get_image_imgsetids(ibs, gid_list): r""" Returns: list_ (list): a list of imageset ids for each image by gid RESTful: Method: GET URL: /api/image/imgsetids/ """ # FIXME: MAKE SQL-METHOD FOR NON-ROWID GETTERS colnames = ('imageset_rowid',) imgsetids_list = ibs.db.get(const.GSG_RELATION_TABLE, colnames, gid_list, id_colname='image_rowid', unpack_scalars=False) return imgsetids_list
@register_ibs_method @accessor_decors.getter_1toM @register_api('/api/image/imagesettext/', methods=['GET'])
[docs]def get_image_imagesettext(ibs, gid_list): r""" Returns: list_ (list): a list of imagesettexts for each image by gid RESTful: Method: GET URL: /api/image/imagesettext/ """ imgsetids_list = ibs.get_image_imgsetids(gid_list) imagesettext_list = ibs.unflat_map(ibs.get_imageset_text, imgsetids_list) return imagesettext_list
ANNOT_ROWID = 'annot_rowid' ANNOT_ROWIDS = 'annot_rowids' IMAGE_ROWID = 'image_rowid' @register_ibs_method @accessor_decors.getter_1toM @accessor_decors.cache_getter(const.IMAGE_TABLE, ANNOT_ROWIDS) #@profile @register_api('/api/image/aids/', methods=['GET'])
[docs]def get_image_aids(ibs, gid_list): r""" Returns: list_ (list): a list of aids for each image by gid Args: ibs (IBEISController): ibeis controller object gid_list (list): Returns: list: aids_list CommandLine: python -m ibeis.control.manual_image_funcs --test-get_image_aids RESTful: Method: GET URL: /api/image/aids/ Example: >>> # DISABLE_DOCTEST >>> from ibeis.control.manual_image_funcs import * # NOQA >>> import ibeis >>> # build test data >>> ibs = ibeis.opendb('testdb1') >>> gid_list = ibs.get_annot_gids(ibs.get_valid_aids()) >>> gid_list = gid_list + gid_list[::5] >>> # execute function >>> aids_list = get_image_aids(ibs, gid_list) >>> # verify results >>> result = str(aids_list) >>> print(result) [[1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [1], [6], [11]] Ignore: print('len(gid_list) = %r' % (len(gid_list),)) print('len(input_list) = %r' % (len(input_list),)) print('len(pair_list) = %r' % (len(pair_list),)) print('len(aidscol) = %r' % (len(aidscol),)) print('len(gidscol) = %r' % (len(gidscol),)) print('len(unique_gids) = %r' % (len(unique_gids),)) """ # FIXME: SLOW JUST LIKE GET_NAME_AIDS # print('gid_list = %r' % (gid_list,)) # FIXME: MAKE SQL-METHOD FOR NON-ROWID GETTERS USE_GROUPING_HACK = False if USE_GROUPING_HACK: input_list, inverse_unique = np.unique(gid_list, return_inverse=True) # This code doesn't work because it doesn't respect empty names input_str = ', '.join(list(map(str, input_list))) opstr = ''' SELECT annot_rowid, image_rowid FROM {ANNOTATION_TABLE} WHERE image_rowid IN ({input_str}) ORDER BY image_rowid ASC, annot_rowid ASC '''.format(input_str=input_str, ANNOTATION_TABLE=const.ANNOTATION_TABLE) pair_list = ibs.db.connection.execute(opstr).fetchall() aidscol = np.array(ut.get_list_column(pair_list, 0)) gidscol = np.array(ut.get_list_column(pair_list, 1)) unique_gids, groupx = vt.group_indices(gidscol) grouped_aids_ = vt.apply_grouping(aidscol, groupx) #aids_list = [sorted(arr.tolist()) for arr in grouped_aids_] structured_aids_list = [arr.tolist() for arr in grouped_aids_] with ut.EmbedOnException(): aids_list = np.array(structured_aids_list)[inverse_unique].tolist() else: USE_NUMPY_IMPL = True # Use qt if getting one at a time otherwise perform bulk operation USE_NUMPY_IMPL = len(gid_list) > 1 if USE_NUMPY_IMPL: # This seems to be 30x faster for bigger inputs valid_aids = np.array(ibs._get_all_aids()) valid_gids = np.array(ibs.db.get_all_col_rows(const.ANNOTATION_TABLE, IMAGE_ROWID)) #np.array(ibs.get_annot_name_rowids(valid_aids, distinguish_unknowns=False)) aids_list = [ valid_aids.take( np.flatnonzero(np.equal(valid_gids, gid))).tolist() for gid in gid_list ] else: # SQL IMPL aids_list = ibs.db.get(const.ANNOTATION_TABLE, (ANNOT_ROWID,), gid_list, id_colname=IMAGE_ROWID, unpack_scalars=False) #print('aids_list = %r' % (aids_list,)) return aids_list
@register_ibs_method @accessor_decors.getter_1toM #@cache_getter(const.IMAGE_TABLE) @register_api('/api/image/aids_of_species/', methods=['GET'])
[docs]def get_image_aids_of_species(ibs, gid_list, species=None): r""" Returns: list_ (list): a list of aids for each image by gid filtered by species RESTful: Method: GET URL: /api/image/aids_of_species/ """ def _filter(aid_list): species_list = ibs.get_annot_species(aid_list) isvalid_list = [ species_ == species for species_ in species_list ] aid_list = ut.compress(aid_list, isvalid_list) return aid_list # Get and filter aids_list aids_list = ibs.get_image_aids(gid_list) if species is None: # We do this so that the species flag behaves nicely with the getter_1toM print('[get_image_aids_of_species] WARNING! Use get_image_aids() instead.') return aids_list aids_list = [ _filter(aid_list) for aid_list in aids_list] return aids_list
@register_ibs_method @accessor_decors.getter_1to1 #@profile @register_api('/api/image/num_annotations/', methods=['GET'])
[docs]def get_image_num_annotations(ibs, gid_list): r""" Returns: list_ (list): the number of chips in each image RESTful: Method: GET URL: /api/image/num_annotations/ """ return list(map(len, ibs.get_image_aids(gid_list)))
@register_ibs_method @accessor_decors.deleter @accessor_decors.cache_invalidator(const.IMAGESET_TABLE, ['percent_imgs_reviewed_str']) @register_api('/api/image/', methods=['DELETE'])
[docs]def delete_images(ibs, gid_list, trash_images=True): r""" deletes images from the database that belong to gids RESTful: Method: DELETE URL: /api/image/ Example: >>> # UNPORTED_DOCTEST >>> gpath_list = grabdata.get_test_gpaths(ndata=None)[0:4] >>> gid_list = ibs.add_images(gpath_list) >>> bbox_list = [(0, 0, 100, 100)] * len(gid_list) >>> name_list = ['a', 'b', 'a', 'd'] >>> aid_list = ibs.add_annots(gid_list, bbox_list=bbox_list, name_list=name_list) >>> gid = gid_list[0] >>> assert gid is not None, "gid is None" >>> aid_list = ibs.get_image_aids(gid) >>> assert len(aid_list) == 1, "Length of aid_list=%r" % (len(aid_list),) >>> aid = aid_list[0] >>> assert aid is not None, "aid is None" >>> cid = ibs.get_annot_chip_rowids(aid, ensure=False) >>> fid = ibs.get_annot_feat_rowids(aid, ensure=False) >>> assert cid is None, "cid=%r should be None" % (cid,) >>> assert fid is None, "fid=%r should be None" % (fid,) >>> cid = ibs.get_annot_chip_rowids(aid, ensure=True) >>> fid = ibs.get_annot_feat_rowids(aid, ensure=True) >>> assert cid is not None, "cid should be computed" >>> assert fid is not None, "fid should be computed" >>> gthumbpath = ibs.get_image_thumbpath(gid) >>> athumbpath = ibs.get_annot_chip_thumbpath(aid) >>> ibs.delete_images(gid) >>> all_gids = ibs.get_valid_gids() >>> all_aids = ibs.get_valid_aids() >>> all_cids = ibs.get_valid_cids() >>> all_fids = ibs.get_valid_fids() >>> assert gid not in all_gids, "gid still exists" >>> assert aid not in all_aids, "rid %r still exists" % aid >>> assert fid not in all_fids, "fid %r still exists" % fid >>> assert cid not in all_cids, "cid %r still exists" % cid >>> assert not utool.checkpath(gthumbpath), "Thumbnail still exists" >>> assert not utool.checkpath(athumbpath), "ANNOTATION Thumbnail still exists" """ if ut.NOT_QUIET: print('[ibs] deleting %d images' % len(gid_list)) # Move images to trash before deleting them. # # TODO: only move localized images # TODO: ensure there are no name conflicts when using the original names gpath_list = ibs.get_image_paths(gid_list) gname_list = ibs.get_image_gnames(gid_list) ext_list = ibs.get_image_exts(gid_list) if trash_images: trash_dir = ibs.get_trashdir() ut.ensuredir(trash_dir) gpath_list2 = [join(trash_dir, gname + ext) for (gname, ext) in zip(gname_list, ext_list)] ut.copy_list(gpath_list, gpath_list2, ioerr_ok=True, oserror_ok=True, lbl='Trashing Images') else: for gpath in gpath_list: ut.delete(gpath) # raise NotImplementedError('must trash images for now') #ut.view_directory(trash_dir) # Delete annotations first aid_list = ut.flatten(ibs.get_image_aids(gid_list)) ibs.delete_annots(aid_list) # delete thumbs in case an annot doesnt delete them # TODO: pass flag to not delete them in delete_annots ibs.delete_image_thumbs(gid_list) ibs.depc_image.delete_root(gid_list) ibs.db.delete_rowids(const.IMAGE_TABLE, gid_list) #gsgrid_list = ut.flatten(ibs.get_image_gsgrids(gid_list)) #ibs.db.delete_rowids(const.GSG_RELATION_TABLE, gsgrid_list) ibs.db.delete(const.GSG_RELATION_TABLE, gid_list, id_colname='image_rowid')
@register_ibs_method @accessor_decors.deleter @register_api('/api/image/thumbs/', methods=['DELETE'])
[docs]def delete_image_thumbs(ibs, gid_list, **config2_): r""" Removes image thumbnails from disk RESTful: Method: DELETE URL: /api/image/thumbs/ Example: >>> # UNPORTED_DOCTEST >>> gpath_list = grabdata.get_test_gpaths(ndata=None)[0:4] >>> gid_list = ibs.add_images(gpath_list) >>> bbox_list = [(0, 0, 100, 100)] * len(gid_list) >>> name_list = ['a', 'b', 'a', 'd'] >>> aid_list = ibs.add_annots(gid_list, bbox_list=bbox_list, >>> name_list=name_list) >>> assert len(aid_list) != 0, "No annotations added" >>> thumbpath_list = ibs.get_image_thumbpath(gid_list) >>> gpath_list = ibs.get_image_paths(gid_list) >>> ibs.delete_image_thumbs(gid_list) >>> assert utool.is_list(thumbpath_list), "thumbpath_list is not a list" >>> assert utool.is_list(gpath_list), "gpath_list is not a list" >>> for path in thumbpath_list: >>> assert not utool.checkpath(path), "Thumbnail not deleted" >>> for path in gpath_list: >>> utool.assertpath(path) """ if ut.NOT_QUIET: print('[ibs] deleting %d image thumbnails' % len(gid_list)) if DEBUG_THUMB: print('{THUMB DELETE} config2_ = %r' % (config2_,)) num_deleted = ibs.depc_image.delete_property('thumbnails', gid_list, config=config2_) # HACK: Remove paths computed by QT and not the depcache. thumbpath_list = ibs.get_image_thumbpath(gid_list, **config2_) print('thumbpath_list = %r' % (thumbpath_list,)) #ut.remove_fpaths(thumbpath_list, quiet=quiet, lbl='image_thumbs') ut.remove_existing_fpaths(thumbpath_list, quiet=True, lbl='image_thumbs') if DEBUG_THUMB: print('num_deleted = %r' % (num_deleted,)) print('{THUMB DELETE} DONE DELETE')
@register_ibs_method #@accessor_decors.cache_getter(const.IMAGE_TABLE, IMAGE_TIMEDELTA_POSIX) @register_api('/api/image/timedelta_posix/', methods=['GET'])
[docs]def get_image_timedelta_posix(ibs, image_rowid_list, eager=True): r""" image_timedelta_posix_list <- image.image_timedelta_posix[image_rowid_list] # TODO: INTEGRATE THIS FUNCTION. CURRENTLY OFFSETS ARE ENCODIED DIRECTLY IN UNIXTIME gets data from the "native" column "image_timedelta_posix" in the "image" table Args: image_rowid_list (list): Returns: list: image_timedelta_posix_list TemplateInfo: Tgetter_table_column col = image_timedelta_posix tbl = image RESTful: Method: GET URL: /api/image/timedelta_posix/ Example: >>> # ENABLE_DOCTEST >>> from ibeis.control.manual_image_funcs import * # NOQA >>> ibs, config2_ = testdata_ibs() >>> image_rowid_list = ibs._get_all_image_rowids() >>> eager = True >>> image_timedelta_posix_list = ibs.get_image_timedelta_posix(image_rowid_list, eager=eager) >>> assert len(image_rowid_list) == len(image_timedelta_posix_list) """ id_iter = image_rowid_list colnames = (IMAGE_TIMEDELTA_POSIX,) image_timedelta_posix_list = ibs.db.get( const.IMAGE_TABLE, colnames, id_iter, id_colname='rowid', eager=eager) return image_timedelta_posix_list
@register_ibs_method @register_api('/api/image/timedelta_posix/', methods=['PUT'])
[docs]def set_image_timedelta_posix(ibs, image_rowid_list, image_timedelta_posix_list, duplicate_behavior='error'): r""" image_timedelta_posix_list -> image.image_timedelta_posix[image_rowid_list] Args: image_rowid_list image_timedelta_posix_list TemplateInfo: Tsetter_native_column tbl = image col = image_timedelta_posix RESTful: Method: PUT URL: /api/image/timedelta_posix/ """ id_iter = image_rowid_list colnames = (IMAGE_TIMEDELTA_POSIX,) ibs.db.set(const.IMAGE_TABLE, colnames, image_timedelta_posix_list, id_iter, duplicate_behavior=duplicate_behavior)
@register_ibs_method #@accessor_decors.cache_getter(const.IMAGE_TABLE, IMAGE_LOCATION_CODE) @register_api('/api/image/location_codes/', methods=['GET'])
[docs]def get_image_location_codes(ibs, image_rowid_list, eager=True): r""" image_location_code_list <- image.image_location_code[image_rowid_list] gets data from the "native" column "image_location_code" in the "image" table Args: image_rowid_list (list): Returns: list: image_location_code_list TemplateInfo: Tgetter_table_column col = image_location_code tbl = image RESTful: Method: GET URL: /api/image/location_codes/ Example: >>> # ENABLE_DOCTEST >>> from ibeis.control.manual_image_funcs import * # NOQA >>> ibs, config2_ = testdata_ibs() >>> image_rowid_list = ibs._get_all_image_rowids() >>> eager = True >>> image_location_code_list = ibs.get_image_location_codes(image_rowid_list, eager=eager) >>> assert len(image_rowid_list) == len(image_location_code_list) """ id_iter = image_rowid_list colnames = (IMAGE_LOCATION_CODE,) image_location_code_list = ibs.db.get( const.IMAGE_TABLE, colnames, id_iter, id_colname='rowid', eager=eager) return image_location_code_list
@register_ibs_method @register_api('/api/image/location_codes/', methods=['PUT'])
[docs]def set_image_location_codes(ibs, image_rowid_list, image_location_code_list, duplicate_behavior='error'): r""" image_location_code_list -> image.image_location_code[image_rowid_list] Args: image_rowid_list image_location_code_list TemplateInfo: Tsetter_native_column tbl = image col = image_location_code RESTful: Method: PUT URL: /api/image/location_codes/ """ id_iter = image_rowid_list colnames = (IMAGE_LOCATION_CODE,) ibs.db.set(const.IMAGE_TABLE, colnames, image_location_code_list, id_iter, duplicate_behavior=duplicate_behavior)
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/party_rowids/', methods=['GET'])
[docs]def get_image_party_rowids(ibs, image_rowid_list, eager=True, nInput=None): r""" party_rowid_list <- image.party_rowid[image_rowid_list] gets data from the "native" column "party_rowid" in the "image" table Args: image_rowid_list (list): Returns: list: party_rowid_list TemplateInfo: Tgetter_table_column col = party_rowid tbl = image RESTful: Method: GET URL: /api/image/party_rowids/ Example: >>> # ENABLE_DOCTEST >>> from ibeis.control.manual_image_funcs import * # NOQA >>> ibs, config2_ = testdata_ibs() >>> image_rowid_list = ibs._get_all_image_rowids() >>> eager = True >>> party_rowid_list = ibs.get_image_party_rowids(image_rowid_list, eager=eager) >>> assert len(image_rowid_list) == len(party_rowid_list) """ id_iter = image_rowid_list colnames = (PARTY_ROWID,) party_rowid_list = ibs.db.get( const.IMAGE_TABLE, colnames, id_iter, id_colname='rowid', eager=eager, nInput=nInput) return party_rowid_list
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/party_tag/', methods=['GET'])
[docs]def get_image_party_tag(ibs, image_rowid_list, eager=True, nInput=None): r""" party_tag_list <- image.party_tag[image_rowid_list] Args: image_rowid_list (list): Returns: list: party_tag_list TemplateInfo: Tgetter_extern tbl = image externtbl = party externcol = party_tag RESTful: Method: GET URL: /api/image/party_tag/ Example: >>> # ENABLE_DOCTEST >>> from ibeis.control.manual_image_funcs import * # NOQA >>> ibs, config2_ = testdata_ibs() >>> image_rowid_list = ibs._get_all_image_rowids() >>> eager = True >>> party_tag_list = ibs.get_image_party_tag(image_rowid_list, eager=eager) >>> assert len(image_rowid_list) == len(party_tag_list) """ party_rowid_list = ibs.get_image_party_rowids( image_rowid_list, eager=eager, nInput=nInput) party_tag_list = ibs.get_party_tag( party_rowid_list, eager=eager, nInput=nInput) return party_tag_list
@register_ibs_method @accessor_decors.setter @register_api('/api/image/party_rowids/', methods=['PUT'])
[docs]def set_image_party_rowids(ibs, image_rowid_list, party_rowid_list, duplicate_behavior='error'): r""" party_rowid_list -> image.party_rowid[image_rowid_list] Args: image_rowid_list party_rowid_list TemplateInfo: Tsetter_native_column tbl = image col = party_rowid RESTful: Method: PUT URL: /api/image/party_rowids/ """ id_iter = image_rowid_list colnames = (PARTY_ROWID,) ibs.db.set(const.IMAGE_TABLE, colnames, party_rowid_list, id_iter, duplicate_behavior=duplicate_behavior)
@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/image/contributor_tag/', methods=['GET'])
[docs]def get_image_contributor_tag(ibs, image_rowid_list, eager=True, nInput=None): r""" contributor_tag_list <- image.contributor_tag[image_rowid_list] Args: image_rowid_list (list): Returns: list: contributor_tag_list TemplateInfo: Tgetter_extern tbl = image externtbl = contributor externcol = contributor_tag RESTful: Method: GET URL: /api/image/contributor_tag/ Example: >>> # ENABLE_DOCTEST >>> from ibeis.control.manual_image_funcs import * # NOQA >>> ibs, config2_ = testdata_ibs() >>> image_rowid_list = ibs._get_all_image_rowids() >>> eager = True >>> contributor_tag_list = ibs.get_image_contributor_tag(image_rowid_list, eager=eager) >>> assert len(image_rowid_list) == len(contributor_tag_list) """ contributor_rowid_list = ibs.get_image_contributor_rowid( image_rowid_list, eager=eager, nInput=nInput) contributor_tag_list = ibs.get_contributor_tag( contributor_rowid_list, eager=eager, nInput=nInput) return contributor_tag_list
[docs]def testdata_ibs(): r""" """ import ibeis ibs = ibeis.opendb('testdb1') config2_ = None return ibs, config2_
if __name__ == '__main__': r""" CommandLine: python -m ibeis.control.manual_image_funcs python -m ibeis.control.manual_image_funcs --allexamples python -m ibeis.control.manual_image_funcs --allexamples --noface --nosrc """ import multiprocessing multiprocessing.freeze_support() # for win32 import utool as ut # NOQA ut.doctest_funcs()