Example #1
0
    def __init__(self,
                 replacement=True,
                 start=0,
                 equalizeCategories=False,
                 *args,
                 **kwargs):
        """
        Args:
            replacement: Whether the same image can be picked multiple times.
            start: Number of random choices to skip at the beginning, useful
                   when seeding the random number generator.
        """
        BaseExplorer.__init__(self, *args, **kwargs)

        if type(replacement) not in (bool, int):
            raise RuntimeError("'replacement' should be a boolean")
        if type(start) is not int:
            raise RuntimeError("'start' should be an integer")

        self.replacement = replacement
        self.start = start
        self.equalizeCategories = equalizeCategories
        self.imagesByCat = None

        if not self.replacement:
            self.history = []
Example #2
0
    def __init__(self, sweepDirections=['left', 'right', 'up', 'down'],
                 shiftDuringSweep=1, sweepOffObject=False, *args, **kwargs):
        """
        Args:
        sweepDirections: Directions for sweeping. Must be a list containing
          one or more of 'left', 'right', 'up', and 'down' for horizontal and
          vertical sweeps, or 'leftup', 'leftdown', 'rightup', and 'rightdown'
          for diagonal sweeps (or 'upleft, 'downleft', 'upright', and
          'downright'). Can also be the string 'all', for all eight directions.
        shiftDuringSweep: Number of pixels to jump with each step (during
          a sweep).
        sweepOffObject: Whether the sensor can only include a part of the
          object, as specified by the bounding box. If False, it will only move
          to positions that include as much of the object as possible.
        """
        BaseExplorer.__init__(self, *args, **kwargs)

        if sweepDirections == 'all':
            sweepDirections = ['left', 'right', 'up', 'down',
              'leftdown', 'leftup', 'rightdown', 'rightup']
        else:
            for direction in sweepDirections:
                if direction not in ('left', 'right', 'up', 'down',
                    'leftup', 'upleft', 'leftdown', 'downleft',
                    'rightup', 'upright', 'rightdown', 'downright'):
                    raise RuntimeError('Unknown sweep direction: %s' % direction)
        if type(shiftDuringSweep) is not int:
            raise RuntimeError("'shiftDuringSweep' should be an integer")
        if type(sweepOffObject) not in (bool, int):
            raise RuntimeError("'sweepOffObject' should be a boolean")

        self.sweepDirections = sweepDirections
        self.shiftDuringSweep = shiftDuringSweep
        self.sweepOffObject = sweepOffObject
Example #3
0
    def __init__(self, sweepDirections=["right", "down"], shiftDuringSweep=1,
                 shiftBetweenSweeps=1, sweepOffObject=False, order=None,
                 *args, **kwargs):
        """
        Args:
            sweepDirections: Directions for sweeping (a list containing one or
                             more of 'left', 'right', 'up', and 'down').
            shiftDuringSweep: Number of pixels to jump with each step (during a
                              sweep).
            shiftBetweenSweeps: Number of pixels to jump in between sweeps
                                (for example, when moving down a line after
                                sweeping across).
            sweepOffObject: Whether the sensor can only include a part of the
                            object, as specified by the bounding box. If False,
                            it will only move to positions that include as much
                            of the object as possible. If True, it will sweep
                            until all of the object moves off the sensor. If
                            set to a floating point number between 0 and 1,
                            then it will sweep until that fraction of the
                            object moves off the sensor.
            order: Order in which to iterate (outer to inner). Default progresses
                   through switching images, filters, and sweeping, where
                   switching images is the outer loop and sweeping is the inner
                   loop. Should be a list containing 'image', 'sweep', and
                   0, 1, ... numFilters-1.
        """
        BaseExplorer.__init__(self, *args, **kwargs)

        for direction in sweepDirections:
            if direction not in ('left', 'right', 'up', 'down'):
                raise RuntimeError("Unknown sweep direction: '%s'" % direction)
        if type(shiftDuringSweep) is not int:
            raise RuntimeError("'shiftDuringSweep' must be an integer")
        if type(shiftBetweenSweeps) is not int:
            raise RuntimeError("'shiftBetweenSweeps' must be an integer")
        if float(sweepOffObject) < 0 or float(sweepOffObject) > 1.0:
            raise RuntimeError("'sweepOffObject' should be a boolean, or floating point"
                               " number between 0 and 1")
        if order is not None:
            if 'image' not in order or 'sweep' not in order:
                raise RuntimeError("'order' must contain both 'image' and 'sweep'")
            if len([x for x in order if type(x) == str]) > 2:
                raise RuntimeError("'order' must contain no other strings besides "
                                   "'image' and 'sweep'")
            self.customOrder = True
        else:
            self.customOrder = False

        self.sweepDirections = sweepDirections
        self.shiftDuringSweep = shiftDuringSweep
        self.shiftBetweenSweeps = shiftBetweenSweeps
        self.sweepOffObject = sweepOffObject
        self.order = order
Example #4
0
    def next(self, seeking=False):
        """Go to the next position (next iteration).

        Args:
            seeking: Boolean that indicates whether the explorer is calling
            next() from seek(). If True, the explorer should avoid unnecessary
            computation that would not affect the seek command. The last call
            to next() from seek() will be with seeking=False.
        """
        BaseExplorer.next(self)

        # If filters were changed, order may be invalid
        if self.order is None or \
            len([x for x in self.order if type(x) == int]) != self.numFilters:
            # If user did not set a custom order, just create new one automatically
            if not self.customOrder:
                self.order = ["image"]
                self.order.extend(range(self.numFilters))
                self.order += ["sweep"]
            # Otherwise, user needs to recreate the explorer with a new order
            else:
                raise RuntimeError(
                    "'order' is invalid. Must recreate explorer with "
                    "valid order after changing filters.")

        if self.position['reset'] and self.blankWithReset:
            # Last iteration was a blank, so don't increment the position
            self.position['reset'] = False
        else:
            self.position['reset'] = False
            for x in reversed(self.order):
                if x == 'image':  # Iterate the image
                    self.position['image'] += 1
                    if self.position['image'] == self.numImages:
                        self.position['image'] = 0
                        self.position['reset'] = True
                    else:
                        break
                elif x == 'sweep':  # Iterate the sweep position
                    nextImage = self._nextSweepPosition()
                    if not nextImage:
                        break
                else:  # Iterate the filter with index x
                    self.position['filters'][x] += 1
                    if self.position['filters'][x] == self.numFilterOutputs[x]:
                        self.position['filters'][x] = 0
                        self.position['reset'] = True
                    else:
                        break
            if nextImage:
                self._firstSweepPosition()
Example #5
0
    def next(self, seeking=False):
        """Go to the next position (next iteration).

        Args:
            seeking: Boolean that indicates whether the explorer is calling
            next() from seek(). If True, the explorer should avoid unnecessary
            computation that would not affect the seek command. The last call
            to next() from seek() will be with seeking=False.
        """
        BaseExplorer.next(self)

        # If filters were changed, order may be invalid
        if self.order is None or \
            len([x for x in self.order if type(x) == int]) != self.numFilters:
            # If user did not set a custom order, just create new one automatically
            if not self.customOrder:
                self.order = ["image"]
                self.order.extend(range(self.numFilters))
                self.order += ["sweep"]
            # Otherwise, user needs to recreate the explorer with a new order
            else:
                raise RuntimeError("'order' is invalid. Must recreate explorer with "
                  "valid order after changing filters.")

        if self.position['reset'] and self.blankWithReset:
            # Last iteration was a blank, so don't increment the position
            self.position['reset'] = False
        else:
            self.position['reset'] = False
            for x in reversed(self.order):
                if x == 'image':  # Iterate the image
                    self.position['image'] += 1
                    if self.position['image'] == self.numImages:
                        self.position['image'] = 0
                        self.position['reset'] = True
                    else:
                        break
                elif x == 'sweep':  # Iterate the sweep position
                    nextImage = self._nextSweepPosition()
                    if not nextImage:
                        break
                else:  # Iterate the filter with index x
                    self.position['filters'][x] += 1
                    if self.position['filters'][x] == self.numFilterOutputs[x]:
                        self.position['filters'][x] = 0
                        self.position['reset'] = True
                    else:
                        break
            if nextImage:
                self._firstSweepPosition()
Example #6
0
    def first(self):
        """Set up the position.

        BaseExplorer picks image 0, offset (0,0), etc., but explorers that wish
        to set a different first position should extend this method. Such
        explorers may wish to call BaseExplorer.first(center=False), which
        initializes the position tuple but does not call centerImage() (which
        could cause unnecessary filtering to occur).
        """
        BaseExplorer.first(self)

        self.directionIndex = 0
        if self.numImages:
            self._firstSweepPosition()
Example #7
0
    def first(self):
        """Set up the position.

        BaseExplorer picks image 0, offset (0,0), etc., but explorers that wish
        to set a different first position should extend this method. Such
        explorers may wish to call BaseExplorer.first(center=False), which
        initializes the position tuple but does not call centerImage() (which
        could cause unnecessary filtering to occur).
        """
        BaseExplorer.first(self)

        self.directionIndex = 0
        if self.numImages:
            self._firstSweepPosition()
Example #8
0
    def seek(self, iteration=None, position=None):
        """Seek to the specified position or iteration.

        Args:
            iteration: Target iteration number (or None).
            position: Target position (or None).

        ImageSensor checks validity of inputs, checks that one (but not both) of
        position and iteration are None, and checks that if position is not None,
        at least one of its values is not None.

        Updates value of position.
        """
        # Zero out the history when seeking to iteration 0. This so we can replicate
        #  how random explorers behave in the vision framework and NVT.
        if iteration is not None and iteration == 0:
            if not self.replacement:
                self.history = []
        BaseExplorer.seek(self, iteration=iteration, position=position)
Example #9
0
    def seek(self, iteration=None, position=None):
        """Seek to the specified position or iteration.

        Args:
            iteration: Target iteration number (or None).
            position: Target position (or None).

        ImageSensor checks validity of inputs, checks that one (but not both) of
        position and iteration are None, and checks that if position is not None,
        at least one of its values is not None.

        Updates value of position.
        """
        # Zero out the history when seeking to iteration 0. This so we can replicate
        #  how random explorers behave in the vision framework and NVT.
        if iteration is not None and iteration == 0:
            if not self.replacement:
                self.history = []
        BaseExplorer.seek(self, iteration=iteration, position=position)
Example #10
0
    def next(self, seeking=False):
        """Go to the next position (next iteration).

        Args:
            seeking: Boolean that indicates whether the explorer is calling
                     next() from seek(). If True, the explorer should avoid
                     unnecessary computation that would not affect the seek
                     command. The last call to next() from seek() will be with
                     seeking=False.
        """
        BaseExplorer.next(self)

        if self.position['reset'] and self.blankWithReset:
            # Last iteration was a blank, so don't increment the position
            self.position['reset'] = False
        else:
            self.position['reset'] = False
            self._nextSweepPosition()
            # Begin a new sweep if necessary
            if self.position['reset']:
                self.first()
Example #11
0
    def __init__(self, replacement=True, start=0, equalizeCategories=False,
                 *args, **kwargs):
        """
        Args:
            replacement: Whether the same image can be picked multiple times.
            start: Number of random choices to skip at the beginning, useful
                   when seeding the random number generator.
        """
        BaseExplorer.__init__(self, *args, **kwargs)

        if type(replacement) not in (bool, int):
            raise RuntimeError("'replacement' should be a boolean")
        if type(start) is not int:
            raise RuntimeError("'start' should be an integer")

        self.replacement = replacement
        self.start = start
        self.equalizeCategories = equalizeCategories
        self.imagesByCat = None

        if not self.replacement:
            self.history = []
Example #12
0
    def first(self, seeking=False):
        """Set up the position.

        BaseExplorer picks image 0, offset (0,0), etc., but explorers that wish
        to set a different first position should extend this method. Such explorers
        may wish to call BaseExplorer.first(center=False), which initializes the
        position tuple but does not call centerImage() (which could cause
        unnecessary filtering to occur).

        Args:
            seeking: Passed from seek() through next() to avoid loading images
                     unnecessarily when seeking
        """
        BaseExplorer.first(self, center=False)

        if not self.numImages:
            return

        if not self.replacement \
           and len(self.history) == self.getNumIterations(None):
            # All images have been visited
            self.history = []

        if self.equalizeCategories:
            # Breakdown the images by category
            if self.imagesByCat is None:
                categoryIndex = []
                for k in range(self.numImages):
                    categoryIndex += [self.getImageInfo(k)['categoryIndex']]
                categories = list(set(categoryIndex))
                numCats = len(categories)

                catPopulation = {}
                imagesByCat = {}
                for catIndex in categories:
                    #catPopulation[catIndex] = len([c for c in categoryIndex if c == catIndex])
                    imagesByCat[catIndex] = [k for k, c in enumerate(categoryIndex) if c == catIndex]
                    catPopulation[catIndex] = len(imagesByCat[catIndex])
                minNumSamples = min([pop for (cat, pop) in catPopulation.items()])
                totalNumSamples = minNumSamples * numCats
                # Store
                self.imagesByCat = imagesByCat
                self.categories = categories
                self.numCategories = numCats
                self.nextCatIndex = 0

            # Pick random image from next category
            thisCat = self.imagesByCat[self.nextCatIndex]
            #randomImageIndex = random.randint(0, len(thisCat))
            self.position['image'] = self.random.choice(thisCat)
            self.position['filters'] = self.pickRandomFilters(self.random)
            self.nextCatIndex = (self.nextCatIndex + 1) % self.numCategories

        else:
            # Pick a random image and set of filters
            while self.start >= 0:

                finished = False
                while not finished:
                    # Pick a position randomly
                    self.position['image'] = self.pickRandomImage(self.random)
                    self.position['filters'] = self.pickRandomFilters(self.random)
                    # Pick again if not replacing and this position has been visited
                    if self.replacement or (self.position['image'],
                       self.position['filters']) not in self.history:
                        finished = True

                if not self.replacement:
                    # Remember this position
                    self.history.append(
                      (self.position['image'], self.position['filters'][:]))

                self.start -= 1

            self.start = 0

        if not seeking:
            self.centerImage()
Example #13
0
    def first(self, seeking=False):
        """Set up the position.

        BaseExplorer picks image 0, offset (0,0), etc., but explorers that wish
        to set a different first position should extend this method. Such explorers
        may wish to call BaseExplorer.first(center=False), which initializes the
        position tuple but does not call centerImage() (which could cause
        unnecessary filtering to occur).

        Args:
            seeking: Passed from seek() through next() to avoid loading images
                     unnecessarily when seeking
        """
        BaseExplorer.first(self, center=False)

        if not self.numImages:
            return

        if not self.replacement \
           and len(self.history) == self.getNumIterations(None):
            # All images have been visited
            self.history = []

        if self.equalizeCategories:
            # Breakdown the images by category
            if self.imagesByCat is None:
                categoryIndex = []
                for k in range(self.numImages):
                    categoryIndex += [self.getImageInfo(k)['categoryIndex']]
                categories = list(set(categoryIndex))
                numCats = len(categories)

                catPopulation = {}
                imagesByCat = {}
                for catIndex in categories:
                    #catPopulation[catIndex] = len([c for c in categoryIndex if c == catIndex])
                    imagesByCat[catIndex] = [
                        k for k, c in enumerate(categoryIndex) if c == catIndex
                    ]
                    catPopulation[catIndex] = len(imagesByCat[catIndex])
                minNumSamples = min(
                    [pop for (cat, pop) in catPopulation.items()])
                totalNumSamples = minNumSamples * numCats
                # Store
                self.imagesByCat = imagesByCat
                self.categories = categories
                self.numCategories = numCats
                self.nextCatIndex = 0

            # Pick random image from next category
            thisCat = self.imagesByCat[self.nextCatIndex]
            #randomImageIndex = random.randint(0, len(thisCat))
            self.position['image'] = self.random.choice(thisCat)
            self.position['filters'] = self.pickRandomFilters(self.random)
            self.nextCatIndex = (self.nextCatIndex + 1) % self.numCategories

        else:
            # Pick a random image and set of filters
            while self.start >= 0:

                finished = False
                while not finished:
                    # Pick a position randomly
                    self.position['image'] = self.pickRandomImage(self.random)
                    self.position['filters'] = self.pickRandomFilters(
                        self.random)
                    # Pick again if not replacing and this position has been visited
                    if self.replacement or (
                            self.position['image'],
                            self.position['filters']) not in self.history:
                        finished = True

                if not self.replacement:
                    # Remember this position
                    self.history.append(
                        (self.position['image'], self.position['filters'][:]))

                self.start -= 1

            self.start = 0

        if not seeking:
            self.centerImage()
Example #14
0
    def first(self):
        """Set up the position.

        BaseExplorer picks image 0, offset (0,0), etc., but explorers that wish
        to set a different first position should extend this method. Such explorers
        may wish to call BaseExplorer.first(center=False), which initializes the
        position tuple but does not call centerImage() (which could cause
        unnecessary filtering to occur).
        """
        BaseExplorer.first(self, center=False)

        if not self.numImages:
            return

        # Pick a random direction and filtered image
        self.direction = self.random.choice(self.sweepDirections)
        self.position['image'] = self.random.randint(0, self.numImages - 1)
        for i in range(self.numFilters):
            self.position['filters'][i] = self.random.randint(0,
              self.numFilterOutputs[i] - 1)
        filteredImages = self.getFilteredImages()

        # Pick a random starting position on the appropriate edge of the image
        sbbox = self._getSweepBoundingBox(filteredImages[0])

        if self.direction == 'left':
            self.position['offset'][0] = sbbox[2] - 1
            self.position['offset'][1] = self.random.randint(sbbox[1], sbbox[3] - 1)
        elif self.direction == 'right':
            self.position['offset'][0] = sbbox[0]
            self.position['offset'][1] = self.random.randint(sbbox[1], sbbox[3] - 1)
        elif self.direction == 'up':
            self.position['offset'][0] = self.random.randint(sbbox[0], sbbox[2] - 1)
            self.position['offset'][1] = sbbox[3] - 1
        elif self.direction == 'down':
            self.position['offset'][0] = self.random.randint(sbbox[0], sbbox[2] - 1)
            self.position['offset'][1] = sbbox[1]
        elif self.direction in ('leftup', 'upleft'):
            if self.random.randint(0, 1):
                self.position['offset'][0] = \
                  self.random.randint(int(sbbox[0] + (sbbox[2] - sbbox[0]) / 2), sbbox[2] - 1)
                self.position['offset'][1] = sbbox[3] - 1
            else:
                self.position['offset'][0] = sbbox[2] - 1
                self.position['offset'][1] = \
                  self.random.randint(int(sbbox[1] + (sbbox[3] - sbbox[1]) / 2), sbbox[3] - 1)
        elif self.direction in ('leftdown', 'downleft'):
            if self.random.randint(0, 1):
                self.position['offset'][0] = \
                  self.random.randint(int(sbbox[0] + (sbbox[2] - sbbox[0]) / 2), sbbox[2] - 1)
                self.position['offset'][1] = sbbox[1]
            else:
                self.position['offset'][0] = sbbox[2] - 1
                self.position['offset'][1] = \
                  self.random.randint(sbbox[1], int(sbbox[3] - 1 - (sbbox[3] - sbbox[1]) / 2))
        elif self.direction in ('rightup', 'upright'):
            if self.random.randint(0, 1):
                self.position['offset'][0] = \
                  self.random.randint(sbbox[0], int(sbbox[2] - 1 - (sbbox[2] - sbbox[0]) / 2))
                self.position['offset'][1] = sbbox[3] - 1
            else:
                self.position['offset'][0] = sbbox[0]
                self.position['offset'][1] = \
                  self.random.randint(int(sbbox[1] + (sbbox[3] - sbbox[1]) / 2), sbbox[3] - 1)
        elif self.direction in ('rightdown', 'downright'):
            if self.random.randint(0, 1):
                self.position['offset'][0] = \
                  self.random.randint(sbbox[0], int(sbbox[2] - 1 - (sbbox[2] - sbbox[0]) / 2))
                self.position['offset'][1] = sbbox[1]
            else:
                self.position['offset'][0] = sbbox[0]
                self.position['offset'][1] = \
                  self.random.randint(sbbox[1], int(sbbox[3] - 1 - (sbbox[3] - sbbox[1]) / 2))

        # Increment the position by a random amount in the range
        # [0, shiftDuringSweep)
        if self.shiftDuringSweep > 1:
            prevShiftDuringSweep = self.shiftDuringSweep
            self.shiftDuringSweep = self.random.randint(0, self.shiftDuringSweep)
            self._nextSweepPosition()
            self.shiftDuringSweep = prevShiftDuringSweep
            if self.position['reset']:
                self.first()

        self.position['reset'] = True
Example #15
0
    def __init__(self,
                 sweepDirections=["right", "down"],
                 shiftDuringSweep=1,
                 shiftBetweenSweeps=1,
                 sweepOffObject=False,
                 order=None,
                 *args,
                 **kwargs):
        """
        Args:
            sweepDirections: Directions for sweeping (a list containing one or
                             more of 'left', 'right', 'up', and 'down').
            shiftDuringSweep: Number of pixels to jump with each step (during a
                              sweep).
            shiftBetweenSweeps: Number of pixels to jump in between sweeps
                                (for example, when moving down a line after
                                sweeping across).
            sweepOffObject: Whether the sensor can only include a part of the
                            object, as specified by the bounding box. If False,
                            it will only move to positions that include as much
                            of the object as possible. If True, it will sweep
                            until all of the object moves off the sensor. If
                            set to a floating point number between 0 and 1,
                            then it will sweep until that fraction of the
                            object moves off the sensor.
            order: Order in which to iterate (outer to inner). Default progresses
                   through switching images, filters, and sweeping, where
                   switching images is the outer loop and sweeping is the inner
                   loop. Should be a list containing 'image', 'sweep', and
                   0, 1, ... numFilters-1.
        """
        BaseExplorer.__init__(self, *args, **kwargs)

        for direction in sweepDirections:
            if direction not in ('left', 'right', 'up', 'down'):
                raise RuntimeError("Unknown sweep direction: '%s'" % direction)
        if type(shiftDuringSweep) is not int:
            raise RuntimeError("'shiftDuringSweep' must be an integer")
        if type(shiftBetweenSweeps) is not int:
            raise RuntimeError("'shiftBetweenSweeps' must be an integer")
        if float(sweepOffObject) < 0 or float(sweepOffObject) > 1.0:
            raise RuntimeError(
                "'sweepOffObject' should be a boolean, or floating point"
                " number between 0 and 1")
        if order is not None:
            if 'image' not in order or 'sweep' not in order:
                raise RuntimeError(
                    "'order' must contain both 'image' and 'sweep'")
            if len([x for x in order if type(x) == str]) > 2:
                raise RuntimeError(
                    "'order' must contain no other strings besides "
                    "'image' and 'sweep'")
            self.customOrder = True
        else:
            self.customOrder = False

        self.sweepDirections = sweepDirections
        self.shiftDuringSweep = shiftDuringSweep
        self.shiftBetweenSweeps = shiftBetweenSweeps
        self.sweepOffObject = sweepOffObject
        self.order = order