示例#1
0
  def __init__(self, sweepDirections=['left', 'right', 'up', 'down'],
               shiftDuringSweep=1, sweepOffObject=False, *args, **kwargs):
    """
    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
示例#2
0
 def __init__(self, sweepLength=4,
                    numRepetitions=1,
                    sweepOffMode=False,
                    maxOffset=None,
                    minVelocity=1,
                    maxVelocity=3,
                    seed=42,
                    *args, **kwargs):
   """
   @param sweepLen: number of presentations per sweep sequence.
   @param numRepetitions: number of times to present each inward sweep.
   """
   BaseExplorer.__init__(self, *args, **kwargs)
   # Parameter checking
   if type(sweepLength) is not int or sweepLength < 1:
     raise RuntimeError("'sweepLength' should be a positive integer")
   if type(numRepetitions) is not int or numRepetitions < 1:
     raise RuntimeError("'numRepetitions' should be a positive integer")
   # Parameters
   self._sweepLength = sweepLength
   self._numRepetitions = numRepetitions
   self._minVelocity = minVelocity
   self._maxVelocity = maxVelocity
   self._sweepOffMode = sweepOffMode
   self._maxOffset = maxOffset
   # Internal state
   self._seqIndex = 0
   self._repIndex = 0
   self._state = None
   self._repMemory = None
   # Prepare PRNG
   self._rng = random.Random()
   self._rng.seed(seed)
示例#3
0
  def __init__(self, numSteps, diagonals=False, jitterSize=0, *args, **kwargs):
    """
    numSteps --
    diagonals -- Whether to step along the diagonal
    jitterSize -- How much to jitter around each step of the onion trajectories.
    """

    BaseExplorer.__init__(self, *args, **kwargs)

    self.numSteps = numSteps
    self.diagonals = diagonals
    if self.diagonals:
      self.offsetDelta = [[-1,-1],[-1,1],[1,1],[1,-1]]
    else:
      self.offsetDelta = [[-numSteps,-numSteps],[-numSteps,numSteps], \
                          [numSteps,numSteps],[numSteps,-numSteps]]
    if jitterSize == 0:
      self.jitter = [[0,0]]
      self.jitterLength = 1
    else:
      # eg. jitterSize = 2 ->
      #         self.jitter = [[-2,0],[-1,0],[1,0],[2,0],
      #                        [0,2],[0,1],[0,-1],[0,-2],
      #                        [0,0]]
      self.jitter = []
      listi = range(-jitterSize,0) + range(1,jitterSize+1)
      for i in listi:
        self.jitter.append([i,0])
      for i in listi:
        self.jitter.append([0,i])
      self.jitter.append([0,0])
      self.jitterLength = len(self.jitter)
      assert(self.jitterLength == 4*jitterSize+1)
示例#4
0
    def __init__(self,
                 radius=1,
                 stepsize=1,
                 minradius=None,
                 includeCenter=False,
                 sweepOffObject=True,
                 randomSelections=0,
                 *args,
                 **kwargs):
        """
    radius - the radius of the spiral sweep
    """

        if minradius is None:
            minradius = stepsize
        assert (radius >= 1)
        if not ((radius >= stepsize) and (radius % stepsize == 0)):
            raise RuntimeError("radius must be a multiple of stepsize")
        if not ((minradius >= stepsize) and (minradius % stepsize == 0)):
            raise RuntimeError("minradius must be a multiple of stepsize")
        if type(sweepOffObject) not in (bool, int):
            raise RuntimeError("'sweepOffObject' should be a boolean")
        BaseExplorer.__init__(self, *args, **kwargs)

        self.sweepOffObject = sweepOffObject

        # Generate a list of possible offsets for this stepsize and radius
        self.offsets = []
        if includeCenter:
            self.offsets += [(0, 0)]
        for i in range(minradius, radius + 1, stepsize):
            # Generate top row (not including sides)
            self.offsets += [(x, -i)
                             for x in range(-i + stepsize, i, stepsize)]

            # Generate right edge (including top row, but not bottom row)
            self.offsets += [(i, y) for y in range(-i, i, stepsize)]

            # Generate bottom edge (not including left edge, including right edge)
            self.offsets += [(x, i) for x in range(i, -i, -stepsize)]

            # Generate left edge (including top and bottom row)
            self.offsets += [(-i, y)
                             for y in range(i, -i - stepsize, -stepsize)]

        self.index = 0

        # User-set parameters to control random selection.
        self.randomSelections = randomSelections
        # The cache of randomly selected offsets for the current image/filter.
        self._selectedOffsets = None
    def __init__(self, shift=1, replacement=True, *args, **kwargs):
        """
    shift -- Number of pixels to move from the center ("radius" of the eye
      movement square).
    replacement -- Whether the same image/position can be picked twice.
    """

        BaseExplorer.__init__(self, *args, **kwargs)

        self.shift = shift
        self.replacement = replacement

        if not self.replacement:
            self.history = []
示例#6
0
  def __init__(self, shift=1, aggregate='sum', *args, **kwargs):
    """
    @param shift -- Number of pixels to move from the center ("radius" of the
      eye movement square).

    @param aggregate -- A function that's used by inference analysis to
      aggregate the results of different eye movement presentations. Valid
      values are 'sum', 'average', 'product' and 'max'. The default is 'sum'.
    """

    BaseExplorer.__init__(self, *args, **kwargs)
    assert aggregate in ('sum', 'average', 'max', 'product')
    self.aggregate_func = aggregate
    self.shift = shift
  def __init__(self, shift=1, replacement=True, *args, **kwargs):
    """
    shift -- Number of pixels to move from the center ("radius" of the eye
      movement square).
    replacement -- Whether the same image/position can be picked twice.
    """

    BaseExplorer.__init__(self, *args, **kwargs)

    self.shift = shift
    self.replacement = replacement

    if not self.replacement:
      self.history = []
示例#8
0
 def __init__(self, radius=4, *args, **kwargs):
   """
   @param radius: the distance from the center, in pixels, at which the
                  sweeps start;
   @param numRepetitions: number of times to present each inward sweep.
   """
   BaseExplorer.__init__(self, *args, **kwargs)
   # Parameter checking
   if type(radius) is not int or radius < 1:
     raise RuntimeError("'radius' should be a positive integer")
   # Parameters
   self._radius = radius
   # Internal state
   self._itersDone = 0
示例#9
0
    def __init__(self, shift=1, aggregate="sum", *args, **kwargs):
        """
    @param shift -- Number of pixels to move from the center ("radius" of the
      eye movement square).

    @param aggregate -- A function that's used by inference analysis to
      aggregate the results of different eye movement presentations. Valid
      values are 'sum', 'average', 'product' and 'max'. The default is 'sum'.
    """

        BaseExplorer.__init__(self, *args, **kwargs)
        assert aggregate in ("sum", "average", "max", "product")
        self.aggregate_func = aggregate
        self.shift = shift
示例#10
0
  def __init__(self, sweepDirections=["right", "down"], shiftDuringSweep=1,
      shiftBetweenSweeps=1, sweepOffObject=False, order=None, *args, **kwargs):
    """
    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
示例#11
0
  def __init__(self, jumpOffObject=False, numJumpsPerImage=None,
               numVisitsPerImage=None, spaceShape=None, *args, **kwargs):
    """
    Parameters:
    -----------------------------------------------------------------
    jumpOffObject:      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.
    numJumpsPerImage:   The number of iterations for which RandomJump
                        should dwell on one image before moving on to the next one.
    numVisitsPerImage:  The number of times RandomJump should visit each
                        image (and do numJumpsPerImage jumps on it).
    spaceShape:         The (height, width) of the 2-D space to explore. This
                        constrains how far away from the center point an image
                        is allowed to be presented.
    """

    BaseExplorer.__init__(self, *args, **kwargs)

    if type(jumpOffObject) not in (bool, int):
      raise RuntimeError("'jumpOffObject' should be a boolean")
    if numJumpsPerImage is not None and type(numJumpsPerImage) is not int:
      raise RuntimeError("'numJumpsPerImage' should be an integer")
    if numVisitsPerImage is not None and type(numVisitsPerImage) is not int:
      raise RuntimeError("'numVisitsPerImage' should be an integer")
    if numVisitsPerImage is not None and numJumpsPerImage is None:
      raise RuntimeError("Must specify 'numJumpsPerImage'"
        " when using 'numVisitsPerImage'")
    if spaceShape is not None and \
       (len(spaceShape) != 2 or spaceShape[0] < 1 or spaceShape[1] < 1):
      raise RuntimeError("'spaceShape' should be a 2-item tuple specifying the"
            "(height, width) of the overall space to explore.")


    self.jumpOffObject = jumpOffObject
    self.numJumpsPerImage = numJumpsPerImage
    self.numVisitsPerImage = numVisitsPerImage
    self.spaceShape = spaceShape

    # Keeps track of how many jumps on this image
    self.numJumpsThisImage = 0
    self.lastImageIndex = None
示例#12
0
  def __init__(self, radius=1, stepsize=1, minradius=None, includeCenter=False,
               sweepOffObject=True, randomSelections=0,
               *args, **kwargs):
    """
    radius - the radius of the spiral sweep
    """

    if minradius is None:
      minradius = stepsize
    assert(radius >= 1)
    if not ((radius >= stepsize) and (radius % stepsize == 0)):
      raise RuntimeError("radius must be a multiple of stepsize")
    if not ((minradius >= stepsize) and (minradius % stepsize == 0)):
      raise RuntimeError("minradius must be a multiple of stepsize")
    if type(sweepOffObject) not in (bool, int):
      raise RuntimeError("'sweepOffObject' should be a boolean")
    BaseExplorer.__init__(self, *args, **kwargs)

    self.sweepOffObject = sweepOffObject

    # Generate a list of possible offsets for this stepsize and radius
    self.offsets = []
    if includeCenter:
      self.offsets += [(0,0)]
    for i in range(minradius, radius+1, stepsize):
      # Generate top row (not including sides)
      self.offsets += [(x, -i) for x in range(-i+stepsize, i, stepsize)]

      # Generate right edge (including top row, but not bottom row)
      self.offsets += [(i, y) for y in range(-i, i, stepsize)]

      # Generate bottom edge (not including left edge, including right edge)
      self.offsets += [(x, i) for x in range(i, -i, -stepsize)]

      # Generate left edge (including top and bottom row)
      self.offsets += [(-i, y) for y in range(i, -i-stepsize, -stepsize)]

    self.index = 0

    # User-set parameters to control random selection.
    self.randomSelections = randomSelections
    # The cache of randomly selected offsets for the current image/filter.
    self._selectedOffsets = None
示例#13
0
  def __init__(self, replacement=True, start=0,
                     equalizeCategories=False,
                      *args, **kwargs):
    """
    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 = []
示例#14
0
    def __init__(self, filename, *args, **kwargs):
        """
    filename -- Path to the file with the pickled dictionary mapping image
      filenames to fixation points.
    """

        BaseExplorer.__init__(self, *args, **kwargs)

        # Load the fixation points
        self.points = pickle.load(open(filename))
        self.pointIndex = None
        self.currentPoints = None

        # Retain just the enclosing directory and filename, not the full path
        self.doSaliencySize = True
        keys = self.points.keys()
        for key in keys:
            path, filename = os.path.split(key)
            key2 = os.path.join(os.path.split(path)[1], filename)
            if key2 != key:
                self.points[key2] = self.points[key]
                self.points.pop(key)
            if "saliencySize" not in self.points[key2]:
                self.doSaliencySize = False
示例#15
0
    def __init__(self,
                 spaceShape=(5, 5),
                 spreadShape=None,
                 spreadRadius=None,
                 stepSize=1,
                 resetEveryPos=False,
                 verbosity=0,
                 *args,
                 **kwargs):
        """
    spaceShape:   The (height, width) of the 2-D space to explore. This
                  sets the number of center-points.
    spreadShape:  The shape (height, width) of the area around each center-point
                  to explore if you want to spread in a square area. If this is
                  specified, then radius must be None.
    spreadRadius: The radius of the spread if you want to spread in a circular
                  area. If this is specified, then spreadShape must be None.
                  When set to R, this explorer will visit all positions where:
                      int(round(sqrt(dx*dx + dy*dy))) <= radius
    stepSize:     The step size. How big each step is, in pixels. This controls
                  *both* the spacing of the center-points within the block and the
                  points we explore around each center-point.

                  When spreadRadius is used to define the spread shape, then it will
                  only visit points within stepSize*spreadRadius of the center
                  point and insure that no two points it visits within this
                  area are closer than stepSize from each other, where distance
                  is defined as: int(round(sqrt(dx*dx + dy*dy)))

                  This euclidean distance is NOT used to determine where the
                  center points are - they are always laid out in a grid with x
                  spacing and y spacing of stepSize.

    resetEveryPos: If False (the default), output a reset only when we first
                  visit a new center point. This is what is normally used for
                  training.
                  If True, then output a reset on every iteration. This is
                  often used for flash inference testing.

    """
        BaseExplorer.__init__(self, *args, **kwargs)

        # Parameter checking
        if type(stepSize) is not int or stepSize < 1:
            raise RuntimeError("'stepSize' should be a positive integer")

        if len(spaceShape) != 2 or spaceShape[0] < 1 or spaceShape[1] < 1:
            raise RuntimeError(
                "'spaceShape' should be a 2-item tuple specifying the"
                "(height, width) of the overall space to explore.")

        if spreadShape is not None:
            if spreadRadius is not None:
                raise RuntimeError(
                    "When spreadShape is used, spreadRadius must be set to None"
                )
            if len(spreadShape
                   ) != 2 or spreadShape[0] < 1 or spreadShape[1] < 1:
                raise RuntimeError(
                    "'spreadShape' should be a 2-item tuple specifying the"
                    "(height, width) of the of the area round each center point to"
                    "explore.")

        if spreadRadius is None and spreadShape is None:
            raise RuntimeError(
                "Either spreadRadius or spreadShape must be defined")

        # Parameters
        self._spaceShape = spaceShape
        self._spreadShape = spreadShape
        self._spreadRadius = spreadRadius
        self._stepSize = stepSize
        self._verbosity = verbosity
        self._resetEveryPos = resetEveryPos

        # =====================================================================
        # Init data structures
        # What is the range on the X and Y offsets of the center points?
        shape = self._spaceShape
        # If the shape is (1,1), special case of just 1 center point
        if shape[0] == 1 and shape[1] == 1:
            self._centerOffsets = [(0, 0)]
        else:
            xMin = -1 * (shape[1] // 2)
            xMax = xMin + shape[1] - 1
            xPositions = range(stepSize * xMin, stepSize * xMax + 1, stepSize)

            yMin = -1 * (shape[0] // 2)
            yMax = yMin + shape[0] - 1
            yPositions = range(stepSize * yMin, stepSize * yMax + 1, stepSize)

            self._centerOffsets = list(cross(yPositions, xPositions))

        self._numCenterOffsets = len(self._centerOffsets)

        # ----------------------------------------------------------------
        # Figure out the spread points based on spreadShape:
        if self._spreadShape is not None:
            # What is the range on the X and Y offsets of the spread points?
            shape = self._spreadShape
            # If the shape is (1,1), special case of no spreading around each center
            #  point
            if shape[0] == 1 and shape[1] == 1:
                self._spreadOffsets = [(0, 0)]
            else:
                xMin = -1 * (shape[1] // 2)
                xMax = xMin + shape[1] - 1
                xPositions = range(stepSize * xMin, stepSize * xMax + 1,
                                   stepSize)

                yMin = -1 * (shape[0] // 2)
                yMax = yMin + shape[0] - 1
                yPositions = range(stepSize * yMin, stepSize * yMax + 1,
                                   stepSize)

                self._spreadOffsets = list(cross(yPositions, xPositions))

                # Put the (0,0) entry first
                self._spreadOffsets.remove((0, 0))
                self._spreadOffsets.insert(0, (0, 0))

        # ---------------------------------------------------------------------
        # Figure out the spread points based on spreadRadius
        else:
            # Special case of spreadRadius = 0:, no spreading around each center point
            if spreadRadius == 0:
                self._spreadOffsets = [(0, 0)]

            # Build up a list of all offsets within spreadRadius * stepSize
            else:
                self._spreadOffsets = []
                for y in range(-spreadRadius * stepSize,
                               spreadRadius * stepSize + 1):
                    for x in range(-spreadRadius * stepSize,
                                   spreadRadius * stepSize + 1):
                        distance = int(round(math.sqrt(x * x + y * y)))
                        if distance > spreadRadius * stepSize:
                            continue
                        # Make sure it's not closer than stepSize to another point within
                        #  the spread
                        if not (x == 0 and y == 0) and stepSize > 1:
                            tooClose = False
                            for (otherY, otherX) in self._spreadOffsets:
                                dx = x - otherX
                                dy = y - otherY
                                distance = int(
                                    round(math.sqrt(dx * dx + dy * dy)))
                                if distance < stepSize:
                                    tooClose = True
                                    break
                            if tooClose:
                                continue
                        self._spreadOffsets.append((y, x))

                # Put the (0,0) entry first
                self._spreadOffsets.remove((0, 0))
                self._spreadOffsets.insert(0, (0, 0))

                if self._verbosity >= 1:
                    print "Visiting spread positions:", self._spreadOffsets

        self._numSpreadOffsets = len(self._spreadOffsets)

        # Set start position
        self._centerPosIdx = 0  # Which center point
        self._spreadPosIdx = 0  # radial position around the center point
示例#16
0
    def __init__(self,
                 dimensions=None,
                 sweepOffObject=False,
                 crossDirectories=False,
                 minSweepLength=0,
                 pattern=None,
                 *args,
                 **kwargs):
        """
    dimensions -- List of dimensions through which to sweep. Each
      element is a string with the name of a dimension, or a dictionary with
      more options (see below). 'translation', is normal translation sweeping,
      and 'image' holds the position constant as it moves across images.
      Include an integer from [0, numFilters-1] to specifying sweeping across
      the outputs of a certain filter while holding the rest of the position
      constant. If None, all dimensions are used, with default options.
    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.
    crossDirectories -- ** DEPRECATED ** If False and sweeping through
      images, the explorer looks at the filename of the images and stops
      sweeping when it would go to an image whose enclosing directory is
      different than the current image.
    minSweepLength -- Minimum length for each sweep. If a sweep is too
      short, image and filter sweeps continue smoothly if 'wraparound' is True,
      and otherwise they switch directions. Translation sweeps bounce into a
      new direction, excluding the opposite direction of the current sweep.
    pattern -- Pattern to use for extracting extra dimensions from
      image filenames. If you use the 'dimensions' argument, make sure to list
      these extra dimensions or they won't be used.
      Sweeps will hold all other dimensions constant while going through the
      selected dimension in sorted order.
      Can either be a tuple: (separator, dimensionName, dimensionName, ...),
      or a regular expression that extracts named dimensions.
      Example:
        If the filenames look like this: "Apple_1 50 90 foo.png", where
        "Apple_1" is the name of the object, "50" is the vertical angle, "90"
        is the horizontal angle, and "foo" is extra text to ignore, MultiSweep
        will sweep through the vertical and horizontal dimensions with either
        of these values for 'pattern' (and ['vertical', 'horizontal'] as the
        value for 'dimensions'):
          Tuple:
            (" ", "object", "vertical", "horizontal", None)
            The separator tells MultiSweep to split up the name on spaces, and
            the None argument specifies that the "foo" part of the name is not
            a dimension and should be ignored.
          Regular expression:
            "^(?P<object>\w+)\s(?P<vertical>\d+)\s(?P<horizontal>\d+)\s\w+$"
            "(?P<NAME>PATTERN)" is a Python-specific syntax for extracting
            named groups.
      Note that "object" is extracted as its own dimension even though it could
      have been ignored. This allows for multiple objects (such as "Apple_1"
      and "Apple_2") to appear in the same directory without MultiSweep
      generating sweeps across objects.
      After the dimensions are extracted, they are converted to ints or floats
      if possible. Then they are sorted using Python's list.sort() method.

    Dictionaries for dimensions take the following keywords:
    name           : Name of the dimension, one of:
                       - 'translation' (translation sweeping)
                       - 'image' (cycle through images)
                       - the name of a dimension extracted via 'pattern'
                       - an integer specifying the index of a filter
    shift          : Number of steps to jump on each iteration.
                     For example, 2 means to jump by 2 pixels or 2 images.
    probability    : Probability of randomly selecting this dimension.
    wraparound     : Whether to 'wrap around' from one end of the dimension to
                     the other, rather than stopping the sweep (or changing
                     directions, if minSweepLength has not been met).
                     ** ONLY IMPLEMENTED FOR SWEEPING THROUGH FILTER OUTPUTS
                     WITH SHIFT == 1 **
    sweepOffObject : Overrides the main 'sweepOffObject' parameter.
    """

        BaseExplorer.__init__(self, *args, **kwargs)

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

        self.sweepOffObject = sweepOffObject
        self.crossDirectories = crossDirectories
        self.minSweepLength = minSweepLength

        # Get dimensions to be parsed from filenames
        self.pattern = pattern
        self.parsedDimensions = []
        if pattern:
            if type(pattern) in (list, tuple):
                if type(pattern) is tuple:
                    pattern = list(pattern)
                self.parsedDimensions = pattern[1:]
                while None in self.parsedDimensions:
                    self.parsedDimensions.remove(None)
            elif isinstance(pattern, basestring):
                self.parsedDimensions = re.findall("\(\?P<([^>]+)>", pattern)
            else:
                raise ValueError("'pattern' should be a list/tuple or string")
            # Extra instance variables for parsed dimensions
            self.parsedIndices = []
            self.parsedIndex = 0

        # Figure out all the dimensions
        if not dimensions:
            self.allDimensions = True
            self.dimensions = ['translation']
            if not self.parsedDimensions:
                self.dimensions.append('image')
        else:
            self.allDimensions = False
            if type(dimensions) in (str, int):
                dimensions = [dimensions]
            self.dimensions = list(dimensions)
            # Add the dimensions to be parsed from filenames
            self.dimensions += self.parsedDimensions
        for i, d in enumerate(self.dimensions):
            if type(d) in (str, int):
                self.dimensions[i] = self._newSweepDictionary(name=d)
            else:
                self.dimensions[i] = self._newSweepDictionary(**d)

        self._calculateProbabilities()
示例#17
0
  def __init__(self, dimensions=None, sweepOffObject=False,
               crossDirectories=False, minSweepLength=0, pattern=None,
               *args, **kwargs):
    """
    dimensions -- List of dimensions through which to sweep. Each
      element is a string with the name of a dimension, or a dictionary with
      more options (see below). 'translation', is normal translation sweeping,
      and 'image' holds the position constant as it moves across images.
      Include an integer from [0, numFilters-1] to specifying sweeping across
      the outputs of a certain filter while holding the rest of the position
      constant. If None, all dimensions are used, with default options.
    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.
    crossDirectories -- ** DEPRECATED ** If False and sweeping through
      images, the explorer looks at the filename of the images and stops
      sweeping when it would go to an image whose enclosing directory is
      different than the current image.
    minSweepLength -- Minimum length for each sweep. If a sweep is too
      short, image and filter sweeps continue smoothly if 'wraparound' is True,
      and otherwise they switch directions. Translation sweeps bounce into a
      new direction, excluding the opposite direction of the current sweep.
    pattern -- Pattern to use for extracting extra dimensions from
      image filenames. If you use the 'dimensions' argument, make sure to list
      these extra dimensions or they won't be used.
      Sweeps will hold all other dimensions constant while going through the
      selected dimension in sorted order.
      Can either be a tuple: (separator, dimensionName, dimensionName, ...),
      or a regular expression that extracts named dimensions.
      Example:
        If the filenames look like this: "Apple_1 50 90 foo.png", where
        "Apple_1" is the name of the object, "50" is the vertical angle, "90"
        is the horizontal angle, and "foo" is extra text to ignore, MultiSweep
        will sweep through the vertical and horizontal dimensions with either
        of these values for 'pattern' (and ['vertical', 'horizontal'] as the
        value for 'dimensions'):
          Tuple:
            (" ", "object", "vertical", "horizontal", None)
            The separator tells MultiSweep to split up the name on spaces, and
            the None argument specifies that the "foo" part of the name is not
            a dimension and should be ignored.
          Regular expression:
            "^(?P<object>\w+)\s(?P<vertical>\d+)\s(?P<horizontal>\d+)\s\w+$"
            "(?P<NAME>PATTERN)" is a Python-specific syntax for extracting
            named groups.
      Note that "object" is extracted as its own dimension even though it could
      have been ignored. This allows for multiple objects (such as "Apple_1"
      and "Apple_2") to appear in the same directory without MultiSweep
      generating sweeps across objects.
      After the dimensions are extracted, they are converted to ints or floats
      if possible. Then they are sorted using Python's list.sort() method.

    Dictionaries for dimensions take the following keywords:
    name           : Name of the dimension, one of:
                       - 'translation' (translation sweeping)
                       - 'image' (cycle through images)
                       - the name of a dimension extracted via 'pattern'
                       - an integer specifying the index of a filter
    shift          : Number of steps to jump on each iteration.
                     For example, 2 means to jump by 2 pixels or 2 images.
    probability    : Probability of randomly selecting this dimension.
    wraparound     : Whether to 'wrap around' from one end of the dimension to
                     the other, rather than stopping the sweep (or changing
                     directions, if minSweepLength has not been met).
                     ** ONLY IMPLEMENTED FOR SWEEPING THROUGH FILTER OUTPUTS
                     WITH SHIFT == 1 **
    sweepOffObject : Overrides the main 'sweepOffObject' parameter.
    """

    BaseExplorer.__init__(self, *args, **kwargs)

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

    self.sweepOffObject = sweepOffObject
    self.crossDirectories = crossDirectories
    self.minSweepLength = minSweepLength

    # Get dimensions to be parsed from filenames
    self.pattern = pattern
    self.parsedDimensions = []
    if pattern:
      if type(pattern) in (list, tuple):
        if type(pattern) is tuple:
          pattern = list(pattern)
        self.parsedDimensions = pattern[1:]
        while None in self.parsedDimensions:
          self.parsedDimensions.remove(None)
      elif isinstance(pattern, basestring):
        self.parsedDimensions = re.findall("\(\?P<([^>]+)>", pattern)
      else:
        raise ValueError("'pattern' should be a list/tuple or string")
      # Extra instance variables for parsed dimensions
      self.parsedIndices = []
      self.parsedIndex = 0

    # Figure out all the dimensions
    if not dimensions:
      self.allDimensions = True
      self.dimensions = ['translation']
      if not self.parsedDimensions:
        self.dimensions.append('image')
    else:
      self.allDimensions = False
      if type(dimensions) in (str, int):
        dimensions = [dimensions]
      self.dimensions = list(dimensions)
      # Add the dimensions to be parsed from filenames
      self.dimensions += self.parsedDimensions
    for i, d in enumerate(self.dimensions):
      if type(d) in (str, int):
        self.dimensions[i] = self._newSweepDictionary(name=d)
      else:
        self.dimensions[i] = self._newSweepDictionary(**d)

    self._calculateProbabilities()
示例#18
0
  def __init__(self, spaceShape=(5,5), spreadShape=None, spreadRadius=None,
                  stepSize=1, resetEveryPos=False, verbosity=0, *args, **kwargs):
    """
    spaceShape:   The (height, width) of the 2-D space to explore. This
                  sets the number of center-points.
    spreadShape:  The shape (height, width) of the area around each center-point
                  to explore if you want to spread in a square area. If this is
                  specified, then radius must be None.
    spreadRadius: The radius of the spread if you want to spread in a circular
                  area. If this is specified, then spreadShape must be None.
                  When set to R, this explorer will visit all positions where:
                      int(round(sqrt(dx*dx + dy*dy))) <= radius
    stepSize:     The step size. How big each step is, in pixels. This controls
                  *both* the spacing of the center-points within the block and the
                  points we explore around each center-point.

                  When spreadRadius is used to define the spread shape, then it will
                  only visit points within stepSize*spreadRadius of the center
                  point and insure that no two points it visits within this
                  area are closer than stepSize from each other, where distance
                  is defined as: int(round(sqrt(dx*dx + dy*dy)))

                  This euclidean distance is NOT used to determine where the
                  center points are - they are always laid out in a grid with x
                  spacing and y spacing of stepSize.

    resetEveryPos: If False (the default), output a reset only when we first
                  visit a new center point. This is what is normally used for
                  training.
                  If True, then output a reset on every iteration. This is
                  often used for flash inference testing.

    """
    BaseExplorer.__init__(self, *args, **kwargs)

    # Parameter checking
    if type(stepSize) is not int or stepSize < 1:
      raise RuntimeError("'stepSize' should be a positive integer")

    if len(spaceShape) != 2 or spaceShape[0] < 1 or spaceShape[1] < 1:
      raise RuntimeError("'spaceShape' should be a 2-item tuple specifying the"
            "(height, width) of the overall space to explore.")

    if spreadShape is not None:
      if spreadRadius is not None:
        raise RuntimeError ("When spreadShape is used, spreadRadius must be set to None")
      if len(spreadShape) != 2 or spreadShape[0] < 1 or spreadShape[1] < 1:
        raise RuntimeError("'spreadShape' should be a 2-item tuple specifying the"
              "(height, width) of the of the area round each center point to"
              "explore.")

    if spreadRadius is None and spreadShape is None:
      raise RuntimeError ("Either spreadRadius or spreadShape must be defined")


    # Parameters
    self._spaceShape = spaceShape
    self._spreadShape = spreadShape
    self._spreadRadius = spreadRadius
    self._stepSize = stepSize
    self._verbosity = verbosity
    self._resetEveryPos = resetEveryPos

    # =====================================================================
    # Init data structures
    # What is the range on the X and Y offsets of the center points?
    shape = self._spaceShape
    # If the shape is (1,1), special case of just 1 center point
    if shape[0] == 1 and shape[1] == 1:
      self._centerOffsets = [(0,0)]
    else:
      xMin = -1 * (shape[1] // 2)
      xMax = xMin + shape[1] - 1
      xPositions = range(stepSize * xMin, stepSize * xMax + 1, stepSize)

      yMin = -1 * (shape[0] // 2)
      yMax = yMin + shape[0] - 1
      yPositions = range(stepSize * yMin, stepSize * yMax + 1, stepSize)

      self._centerOffsets = list(cross(yPositions, xPositions))

    self._numCenterOffsets = len(self._centerOffsets)


    # ----------------------------------------------------------------
    # Figure out the spread points based on spreadShape:
    if self._spreadShape is not None:
      # What is the range on the X and Y offsets of the spread points?
      shape = self._spreadShape
      # If the shape is (1,1), special case of no spreading around each center
      #  point
      if shape[0] == 1 and shape[1] == 1:
        self._spreadOffsets = [(0,0)]
      else:
        xMin = -1 * (shape[1] // 2)
        xMax = xMin + shape[1] - 1
        xPositions = range(stepSize * xMin, stepSize * xMax + 1, stepSize)

        yMin = -1 * (shape[0] // 2)
        yMax = yMin + shape[0] - 1
        yPositions = range(stepSize * yMin, stepSize * yMax + 1, stepSize)

        self._spreadOffsets = list(cross(yPositions, xPositions))

        # Put the (0,0) entry first
        self._spreadOffsets.remove((0,0))
        self._spreadOffsets.insert(0, (0,0))

    # ---------------------------------------------------------------------
    # Figure out the spread points based on spreadRadius
    else:
      # Special case of spreadRadius = 0:, no spreading around each center point
      if spreadRadius == 0:
        self._spreadOffsets = [(0,0)]

      # Build up a list of all offsets within spreadRadius * stepSize
      else:
        self._spreadOffsets = []
        for y in range(-spreadRadius*stepSize, spreadRadius*stepSize+1):
          for x in range(-spreadRadius*stepSize, spreadRadius*stepSize+1):
            distance = int(round(math.sqrt(x*x + y*y)))
            if distance > spreadRadius*stepSize:
              continue
            # Make sure it's not closer than stepSize to another point within
            #  the spread
            if not (x==0 and y==0) and stepSize > 1:
              tooClose = False
              for (otherY, otherX) in self._spreadOffsets:
                dx = x - otherX
                dy = y - otherY
                distance = int(round(math.sqrt(dx*dx + dy*dy)))
                if distance < stepSize:
                  tooClose = True
                  break
              if tooClose:
                continue
            self._spreadOffsets.append((y,x))

        # Put the (0,0) entry first
        self._spreadOffsets.remove((0,0))
        self._spreadOffsets.insert(0, (0,0))

        if self._verbosity >= 1:
          print "Visiting spread positions:", self._spreadOffsets

    self._numSpreadOffsets = len(self._spreadOffsets)

    # Set start position
    self._centerPosIdx = 0       # Which center point
    self._spreadPosIdx = 0       # radial position around the center point