Esempio n. 1
0
 def __init__(self, database):
     self._convert = os.path.abspath(config.get('thumbnail',
                                                'convert_path'))
     self._lock_file = os.path.abspath(
         config.get('thumbnail', 'lock_file') + '-' + database)
     self._size = int(config.get('thumbnail', 'image_size'))
     self._database = rigor.database.Database.instance(database)
     os.umask(002)
Esempio n. 2
0
	def __init__(self, move=True):
		self._source = os.path.abspath(config.get('import', 'upload_repository')) + os.sep
		self._destination = os.path.abspath(config.get('global', 'image_repository')) + os.sep
		self._move = move

		rsync = os.path.abspath(config.get('import', 'rsync_path'))

		args = [rsync, '-q', '-r', '-p', '--chmod=ugo+r,Dugo+x,ug+w', '-t', '-O']
		if move:
			args.append('--remove-source-files')
		args.append(self._source)
		args.append(self._destination)
		self._args = args
		os.umask(002)
Esempio n. 3
0
def find_thumbnail(image, size):
    """
	Given a base path, constructs a path to the image's thumbnail
	"""
    return build_thumbnail_path(image,
                                config.get('thumbnail', 'image_repository'),
                                size)
Esempio n. 4
0
	def _read_global_metadata(self):
		""" Reads the metadata file for the image directory and sets defaults """
		metadata_file = os.path.join(self._directory, config.get('import', 'metadata_file'))
		if not os.path.isfile(metadata_file):
			return
		with open(metadata_file, 'r') as metadata:
			return json.load(metadata)
Esempio n. 5
0
def destroy_image(database, image):
	""" Completely Removes an image from the database, along with its tags, annotations, and any anotation tags. Also deletes the image file from disk."""
	mapper = DatabaseMapper(database)
	with database.get_cursor() as cursor:
		sql = "DELETE FROM tag WHERE image_id = %s;"
		cursor.execute(sql, (image['id'],))
		annotations = mapper._get_annotations_by_image_id(cursor, image['id']) # pylint: disable=W0212
		for annotation in annotations:
			sql = "DELETE FROM annotation_tag WHERE annotation_id = %s"
			cursor.execute(sql, (annotation['id'],))
			mapper._delete_annotation(cursor, annotation['id']) # pylint: disable=W0212
		sql = "DELETE FROM image WHERE id = %s;"
		cursor.execute(sql, (image['id'],))
		image_path = find(image)
		os.unlink(image_path)
		for thumbnail_dir in os.listdir(config.get('thumbnail', 'image_repository')):
			image_thumbnail_path = build_path(image, os.path.join(config.get('thumbnail', 'image_repository'), thumbnail_dir))
			os.unlink(image_thumbnail_path)
Esempio n. 6
0
	def build_dsn(database):
		""" Builds the database connection string from config values """
		dsn = "dbname='{0}' host='{1}'".format(database, config.get('database', 'host'))
		try:
			ssl = config.getboolean('database', 'ssl')
			if ssl:
				dsn += " sslmode='require'"
		except ConfigParser.Error:
			pass
		try:
			username = config.get('database', 'username')
			dsn += " user='******'".format(username)
		except ConfigParser.Error:
			pass
		try:
			password = config.get('database', 'password')
			dsn += " password='******'".format(password)
		except ConfigParser.Error:
			pass
		return dsn
Esempio n. 7
0
 def build_dsn(database):
     """ Builds the database connection parameters from config values """
     dsn = {'database': database, 'host': config.get('database', 'host')}
     try:
         ssl = config.getboolean('database', 'ssl')
         if ssl:
             dsn['ssl'] = ssl
     except ConfigParser.Error:
         pass
     try:
         username = config.get('database', 'username')
         dsn['user'] = username
     except ConfigParser.Error:
         pass
     try:
         password = config.get('database', 'password')
         dsn['password'] = password
     except ConfigParser.Error:
         pass
     return dsn
Esempio n. 8
0
	def __init__(self, algorithm, domain, arguments=None):
		"""
		The domain dictates which images to use as sources. The limit is an
		optional maximum number of images to use as sources.  If random, images
		will be pulled in random order, up to limit; otherwise, images will be
		pulled in sequential order.  Tags are used to control the image selection
		further.
		"""
		DatabaseRunner.__init__(self, algorithm, arguments)
		self._domain = domain
		self._image_id = None
		if kMaxWorkers > 1:
			self._pool = Pool(int(config.get('global', 'max_workers')))
Esempio n. 9
0
def destroy_image(database, image):
    """ Completely Removes an image from the database, along with its tags, annotations, and any anotation tags. Also deletes the image file from disk."""
    mapper = DatabaseMapper(database)
    with database.get_cursor() as cursor:
        sql = "DELETE FROM tag WHERE image_id = %s;"
        cursor.execute(sql, (image['id'], ))
        annotations = mapper._get_annotations_by_image_id(cursor, image['id'])  # pylint: disable=W0212
        for annotation in annotations:
            sql = "DELETE FROM annotation_tag WHERE annotation_id = %s"
            cursor.execute(sql, (annotation['id'], ))
            mapper._delete_annotation(cursor, annotation['id'])  # pylint: disable=W0212
        sql = "DELETE FROM image WHERE id = %s;"
        cursor.execute(sql, (image['id'], ))
        image_path = find(image)
        os.unlink(image_path)
        for thumbnail_dir in os.listdir(
                config.get('thumbnail', 'image_repository')):
            image_thumbnail_path = build_path(
                image,
                os.path.join(config.get('thumbnail', 'image_repository'),
                             thumbnail_dir))
            os.unlink(image_thumbnail_path)
Esempio n. 10
0
def main():
	rigor.domain.money.init(parameters)
	logger = rigor.logger.getLogger(__file__)
	database_mapper = DatabaseMapper(Database.instance(kDatabase))
	pool = Pool(int(config.get('global', 'max_workers')))
	logger.debug('Fetching image IDs from database')
	images = database_mapper.get_images_for_analysis(kDomain, kLimit, False)
	for parameter_set in get_parameters():
		timestamp = datetime.utcnow().strftime("{0}-%Y%m%d_%H%M%S%f".format(kDomain))
		with open("{0}.params".format(timestamp), "w") as parameter_file:
			json.dump(parameter_set, parameter_file)
			parameter_file.write("\n")

		with open("{0}.results".format(timestamp), "w") as result_file:
			image_config = partial(rigor.domain.money.run, parameters=parameter_set)
			logger.debug('Processing {0} images'.format(len(images)))
			for result in pool.map(image_config, images):
				result_file.write("\t".join([str(x) for x in result]))
				result_file.write("\n")
Esempio n. 11
0
def main():
    rigor.domain.money.init(parameters)
    logger = rigor.logger.getLogger(__file__)
    database_mapper = DatabaseMapper(Database.instance(kDatabase))
    pool = Pool(int(config.get('global', 'max_workers')))
    logger.debug('Fetching image IDs from database')
    images = database_mapper.get_images_for_analysis(kDomain, kLimit, False)
    for parameter_set in get_parameters():
        timestamp = datetime.utcnow().strftime(
            "{0}-%Y%m%d_%H%M%S%f".format(kDomain))
        with open("{0}.params".format(timestamp), "w") as parameter_file:
            json.dump(parameter_set, parameter_file)
            parameter_file.write("\n")

        with open("{0}.results".format(timestamp), "w") as result_file:
            image_config = partial(rigor.domain.money.run,
                                   parameters=parameter_set)
            logger.debug('Processing {0} images'.format(len(images)))
            for result in pool.map(image_config, images):
                result_file.write("\t".join([str(x) for x in result]))
                result_file.write("\n")
Esempio n. 12
0
	def __init__(self, database):
		self._convert = os.path.abspath(config.get('thumbnail', 'convert_path'))
		self._lock_file = os.path.abspath(config.get('thumbnail', 'lock_file') + '-' + database)
		self._size = int(config.get('thumbnail', 'image_size'))
		self._database = rigor.database.Database.instance(database)
		os.umask(002)
Esempio n. 13
0
	def import_image(self, path, basename, metadata):
		""" Reads the metadata for an invididual image and returns an object ready to insert """
		image = dict()
		image['locator'] = uuid.uuid4().hex
		image['hash'] = rigor.hash.sha1_hash(path)

		data = rigor.imageops.read(path)
		image['resolution'] = (data.shape[1], data.shape[0])
		image['format'] = imghdr.what(path)
		if not image['format']:
			image['format'] = 'jpeg' # TODO: why is imghdr.what returning None for /home/kaolin/data/ICDAR2005SceneCompetition/wltang_15.08.2002/IMG_0001.JPG
		if len(data.shape) == 2:
			image['depth'] = 8
		else:
			image['depth'] = data.shape[2] * 8

		if not metadata:
			metadata = {};
		new_metadata = metadata.copy()
		new_metadata.update(self._read_local_metadata(basename))
		if 'timestamp' in new_metadata:
			image['stamp'] = datetime.strptime(new_metadata['timestamp'], config.get('import', 'timestamp_format'))
		else:
			image['stamp'] = datetime.utcfromtimestamp(os.path.getmtime(path))
		if 'source_id' in new_metadata:
			image['source_id'] = new_metadata['source_id']
		else:
			image['source_id'] = None

		image['tags'] = list()
		if 'tags' in new_metadata:
			image['tags'] = new_metadata['tags']
		has_sensor = False
		for tag in image['tags']:
			if tag.startswith('sensor:'):
				has_sensor = True
				break
		if not has_sensor:
			try:
				exif = pyexiv2.ImageMetadata(path) # pylint: disable=E0602
				exif.read()
				if 'Exif.Image.Make' in exif and 'Exif.Image.Model' in exif:
					sensor_tag = 'sensor:' + '_'.join((exif['Exif.Image.Make'].value, exif['Exif.Image.Model'].value))
					image['tags'] += sensor_tag.lower()
			except NameError:
				self._logger.warning("Image at {0}: No sensor listed in metadata, and EXIF data is not available.".format(path))

		if 'location' in new_metadata:
			image['location'] = new_metadata['location']
		else:
			image['location'] = None

		annotations = list()
		if 'annotations' in new_metadata:
			for annotation in new_metadata['annotations']:
				new_annotations = dict()
				for key in ('boundary', 'domain', 'model', 'confidence', 'annotation_tags'):
					if key in annotation:
						new_annotations[key] = annotation[key]
					else:
						new_annotations[key] = None
				if 'timestamp' in annotation:
					new_annotations['stamp'] = datetime.strptime(annotation['timestamp'], config.get('import', 'timestamp_format'))
				else:
					new_annotations['stamp'] = image['stamp']
				annotations.append(new_annotations)
		image['annotations'] = annotations

		destination = os.path.join(config.get('import', 'upload_repository'), image['locator'][0:2], image['locator'][2:4], os.extsep.join((image['locator'], image['format'])))
		# We take control of the transaction here so we can fail if copying/moving the file fails
		try:
			with self._database_mapper._db.get_cursor() as cursor: # pylint: disable=W0212
				self._database_mapper._create_image(cursor, image) # pylint: disable=W0212
				# Create destination directory, if it doesn't already exist.  try/except
				# structure avoids race condition
				try:
					os.makedirs(os.path.dirname(destination))
				except OSError as err:
					if err.errno == errno.EEXIST:
						pass
					else:
						raise
				if self._move:
					shutil.move(path, destination)
				else:
					shutil.copy2(path, destination)
				os.chmod(destination, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IROTH)
				self._logger.info("Imported image {0}".format(image['locator']))
				return image
		except rigor.database.IntegrityError:
			self._logger.warn("The image at '{0}' already exists in the database".format(path))
Esempio n. 14
0
	def cls():
		adapter_name = config.get('database', 'adapter')
		adapter = __import__("rigor.adapters.{}_adapter".format(adapter_name), fromlist=["rigor.adapters", ])
		return adapter.Database
Esempio n. 15
0
def find(image):
	"""
	Returns the location in the repository where this image can be found.
	"""
	return build_path(image, config.get('global', 'image_repository'))
Esempio n. 16
0
def find(image):
    """
	Returns the location in the repository where this image can be found.
	"""
    return build_path(image, config.get('global', 'image_repository'))
Esempio n. 17
0
"""
Runs an algorithm across a set of images.  Result is a report containing image
ID, detected model, expected model, and elapsed time
"""
from rigor.config import config

import rigor.logger
import rigor.database
import rigor.dbmapper

import abc
import json
import argparse

kMaxWorkers = int(config.get('global', 'max_workers'))
if kMaxWorkers > 1:
	from multiprocessing.pool import Pool

class BaseRunner(object):
	"""
	The base class for Runner objects, which fetch a set of images and apply
	the Algorithm instance to each
	"""
	__metaclass__ = abc.ABCMeta

	def __init__(self, algorithm, arguments=None):
		self._logger = rigor.logger.get_logger('.'.join((__name__, self.__class__.__name__)))
		self._algorithm = algorithm
		self._parameters = None
		self._arguments = None
		self.parse_arguments(arguments)
Esempio n. 18
0
	def __init__(self, database):
		super(Database, self).__init__(database)
		register_type(psycopg2.extensions.UNICODE)
		register_uuid()
		dsn = Database.build_dsn(database)
		self._pool = ThreadedConnectionPool(config.get('database', 'min_database_connections'), config.get('database', 'max_database_connections'), dsn)
Esempio n. 19
0
def find_thumbnail(image, size):
	"""
	Given a base path, constructs a path to the image's thumbnail
	"""
	return build_thumbnail_path(image, config.get('thumbnail', 'image_repository'), size)