コード例 #1
0
  def __init__(self, replacement=True, saccadeMin=10, saccadeMax=10,
               numSaccades=8, maxDrift=0,
               *args, **kwargs):
    """
    :param replacement: Allow the explorer to repeat images (if true)
    :param saccadeMin: Minimum distance a saccade will travel (in px)
    :param saccadeMax: Maxium distance a saccade will travel (in px)
    :param numSaccades: Number of saccades to run over each image
    :param maxDrift: Amount (in px) a saccade's center (fovea) can move out
      of the bounds of the image
    """
    BaseExplorer.__init__(self, *args, **kwargs)

    self.replacement = replacement
    self.saccadeMin = saccadeMin
    self.saccadeMax = saccadeMax
    self.numSaccades = numSaccades
    self.maxDrift = maxDrift

    self.prevSaccade = None

    if not self.replacement:
      self.history = []
      self.imageHistory = []

    self.saccadeIndex = 0
コード例 #2
0
ファイル: MultiSweep.py プロジェクト: CV-IP/nupic.vision
  def update(self, **kwargs):
    """
    Update state with new parameters from ImageSensor and call first().
    """

    numFilters = kwargs.get('numFilters', None)
    if numFilters is not None and self.allDimensions:
      # Remove existing filter dimensions
      for dimension in self.dimensions[:]:
        if type(dimension['name']) is int:
          self.dimensions.remove(dimension)
      # Reset the probabilities from the existing dimensions
      for d in self.dimensions:
        d['probability'] = None
      # Add the new filter dimensions
      self.dimensions += \
        [self._newSweepDictionary(name=name) for name in range(numFilters)]

    numImages = kwargs.get('numImages', None)
    if numImages is not None and self.pattern:
      # Parse all the filenames
      self._parseFilenames(numImages)

    self._calculateProbabilities()

    BaseExplorer.update(self, **kwargs)
コード例 #3
0
ファイル: OnionSweep.py プロジェクト: jaredweiss/nupic.vision
  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 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=True)

        # Update the "home" position for the current image
        self._getHomePosition()

        if self._verbosity >= 1:
            print "BlockSpread: first():"

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

        # Convert to X and Y offsets
        self._getPosition()
コード例 #5
0
ファイル: ManualSaliency.py プロジェクト: CV-IP/nupic.vision
  def next(self, seeking=False):
    """
    Go to the next position (next iteration).

    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.pointIndex is None:
      self.first()

    self.pointIndex += 1
    if self.pointIndex < len(self.currentPoints):
      # Next fixation point for this image
      self._setOffset()
    else:
      # Ran out of points for this image
      image = self.position['image'] + 1
      if image >= self.numImages:
        self.first()
        return
      while not self.names[image] in self.points:
        image += 1
        if image >= self.numImages:
          self.first()
          return
      self.position['image'] = image
      self._firstPoint()
コード例 #6
0
ファイル: ManualSaliency.py プロジェクト: CV-IP/nupic.vision
  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)

    if not self.numImages:
      return

    # Set up the list of filenames
    self.names = []
    for i in xrange(self.numImages):
      path, filename = os.path.split(self.getImageInfo(i)['imagePath'])
      name = os.path.join(os.path.split(path)[1], filename)
      self.names.append(name)

    # Find the first image with some fixation points
    image = 0
    while not self.names[image] in self.points:
      # No fixation points for this image
      image += 1
      if image >= self.numImages:
        raise RuntimeError("No fixation points for any loaded images")
    self.position['image'] = image
    self._firstPoint()
    self.position['reset'] = True
コード例 #7
0
    def update(self, **kwargs):
        """
    Update state with new parameters from ImageSensor and call first().
    """

        numFilters = kwargs.get('numFilters', None)
        if numFilters is not None and self.allDimensions:
            # Remove existing filter dimensions
            for dimension in self.dimensions[:]:
                if type(dimension['name']) is int:
                    self.dimensions.remove(dimension)
            # Reset the probabilities from the existing dimensions
            for d in self.dimensions:
                d['probability'] = None
            # Add the new filter dimensions
            self.dimensions += \
              [self._newSweepDictionary(name=name) for name in range(numFilters)]

        numImages = kwargs.get('numImages', None)
        if numImages is not None and self.pattern:
            # Parse all the filenames
            self._parseFilenames(numImages)

        self._calculateProbabilities()

        BaseExplorer.update(self, **kwargs)
コード例 #8
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)
コード例 #9
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
コード例 #10
0
  def __init__(self, replacement=True, saccadeMin=10, saccadeMax=10,
               numSaccades=8, maxDrift=0,
               *args, **kwargs):
    """
    :param replacement: Allow the explorer to repeat images (if true)
    :param saccadeMin: Minimum distance a saccade will travel (in px)
    :param saccadeMax: Maxium distance a saccade will travel (in px)
    :param numSaccades: Number of saccades to run over each image
    :param maxDrift: Amount (in px) a saccade's center (fovea) can move out
      of the bounds of the image
    """
    BaseExplorer.__init__(self, *args, **kwargs)

    self.replacement = replacement
    self.saccadeMin = saccadeMin
    self.saccadeMax = saccadeMax
    self.numSaccades = numSaccades
    self.maxDrift = maxDrift

    self.prevSaccade = None

    if not self.replacement:
      self.history = []
      self.imageHistory = []

    self.saccadeIndex = 0
コード例 #11
0
ファイル: BlockSpread.py プロジェクト: CV-IP/nupic.vision
  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=True)

    # Update the "home" position for the current image
    self._getHomePosition()

    if self._verbosity >= 1:
      print "BlockSpread: first():"

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

    # Convert to X and Y offsets
    self._getPosition()
コード例 #12
0
ファイル: RandomJump.py プロジェクト: ywcui1990/nupic.vision
    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

        isBlank = True
        while isBlank:

            # Pick a random position
            if not self.numJumpsPerImage or self.lastImageIndex is None or \
                (self.numJumpsThisImage % self.numJumpsPerImage == 0):
                # Pick new image
                image = self.pickRandomImage(self.random)
                self.lastImageIndex = image
                self.numJumpsThisImage = 0
            else:
                image = self.lastImageIndex
            self.position['image'] = image
            self.position['filters'] = self.pickRandomFilters(self.random)
            filteredImages = self.getFilteredImages()

            # Pick a random offset
            if self.spaceShape is not None:
                self.centerImage()
                # NOTE: self.position['offset'] is (x, y), whereas our spaceShape is
                #  (height, width). Also note that the self.position['offset']
                #  direction is counter-intuitive: negative numbers move us to the RIGHT
                #  and DOWN instead of LEFT and UP.
                xOffset = self.random.randint(-(self.spaceShape[1] // 2),
                                              self.spaceShape[1] // 2)
                yOffset = self.random.randint(-(self.spaceShape[0] // 2),
                                              self.spaceShape[0] // 2)
                #print "(yOffset, xOffset) = ", yOffset, xOffset
                self.position['offset'][0] += xOffset
                self.position['offset'][1] += yOffset

            else:
                ebbox = self._getEffectiveBoundingBox(filteredImages[0])
                self.position['offset'] = [
                    self.random.randint(ebbox[0], ebbox[2] - 1),
                    self.random.randint(ebbox[1], ebbox[3] - 1)
                ]

            # Check if the position is blank
            isBlank = self.isBlank(self.jumpOffObject)

        self.position['reset'] = True
        self.numJumpsThisImage += 1
コード例 #13
0
ファイル: RandomJump.py プロジェクト: jaredweiss/nupic.vision
  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

    isBlank = True
    while isBlank:

      # Pick a random position
      if not self.numJumpsPerImage or self.lastImageIndex is None or \
          (self.numJumpsThisImage % self.numJumpsPerImage == 0):
        # Pick new image
        image = self.pickRandomImage(self.random)
        self.lastImageIndex = image
        self.numJumpsThisImage = 0
      else:
        image = self.lastImageIndex
      self.position['image'] = image
      self.position['filters'] = self.pickRandomFilters(self.random)
      filteredImages = self.getFilteredImages()

      # Pick a random offset
      if self.spaceShape is not None:
        self.centerImage()
        # NOTE: self.position['offset'] is (x, y), whereas our spaceShape is
        #  (height, width). Also note that the self.position['offset']
        #  direction is counter-intuitive: negative numbers move us to the RIGHT
        #  and DOWN instead of LEFT and UP.
        xOffset = self.random.randint(-(self.spaceShape[1]//2), self.spaceShape[1]//2)
        yOffset = self.random.randint(-(self.spaceShape[0]//2), self.spaceShape[0]//2)
        #print "(yOffset, xOffset) = ", yOffset, xOffset
        self.position['offset'][0] += xOffset
        self.position['offset'][1] += yOffset

      else:
        ebbox = self._getEffectiveBoundingBox(filteredImages[0])
        self.position['offset'] = [
          self.random.randint(ebbox[0], ebbox[2]-1),
          self.random.randint(ebbox[1], ebbox[3]-1)
        ]

      # Check if the position is blank
      isBlank = self.isBlank(self.jumpOffObject)

    self.position['reset'] = True
    self.numJumpsThisImage += 1
コード例 #14
0
    def next(self, seeking=False):
        """
    Go to the next position (next iteration).

    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)
        self._computeNextPosn()
コード例 #15
0
ファイル: OnionBlock.py プロジェクト: jaredweiss/nupic.vision
  def next(self, seeking=False):
    """
    Go to the next position (next iteration).

    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)
    self._computeNextPosn()
コード例 #16
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)
    self._computeNextPosn()
コード例 #17
0
    def next(self, seeking=False):
        """
    Go to the next position (next iteration).

    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._verbosity >= 1:
            print "BlockSpread: next():"

        # ========================================================================
        # Update to next position
        self._spreadPosIdx += 1
        if self._spreadPosIdx == self._numSpreadOffsets:
            self._spreadPosIdx = 0
            self._centerPosIdx += 1

            # If we've run through all the center positions, advance to the next
            #  filtered image
            if self._centerPosIdx == self._numCenterOffsets:
                self._centerPosIdx = 0

                # --------------------------------------------------------------------
                # Go to next filter for this image, or next image
                # Iterate through the filters first
                needNewImage = True
                for i in xrange(self.numFilters):
                    self.position['filters'][i] += 1
                    if self.position['filters'][i] < self.numFilterOutputs[i]:
                        needNewImage = False
                        break
                    else:
                        self.position['filters'][i] = 0

                # Go to the next image if ready
                if needNewImage:
                    self.position['image'] += 1
                    if self.position['image'] == self.numImages:
                        self.position['image'] = 0

                # -----------------------------------------------------------------
                # Get the home position for this new filtered image
                self._getHomePosition()

        # ========================================================================
        # Get the X,Y corrdinates and reset signal
        if not seeking:
            self._getPosition()
コード例 #18
0
ファイル: BlockSpread.py プロジェクト: CV-IP/nupic.vision
  def next(self, seeking=False):
    """
    Go to the next position (next iteration).

    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._verbosity >= 1:
      print "BlockSpread: next():"

    # ========================================================================
    # Update to next position
    self._spreadPosIdx += 1
    if self._spreadPosIdx == self._numSpreadOffsets:
      self._spreadPosIdx = 0
      self._centerPosIdx += 1

      # If we've run through all the center positions, advance to the next
      #  filtered image
      if self._centerPosIdx == self._numCenterOffsets:
        self._centerPosIdx = 0

        # --------------------------------------------------------------------
        # Go to next filter for this image, or next image
        # Iterate through the filters first
        needNewImage = True
        for i in xrange(self.numFilters):
          self.position['filters'][i] += 1
          if self.position['filters'][i] < self.numFilterOutputs[i]:
            needNewImage = False
            break
          else:
            self.position['filters'][i] = 0

        # Go to the next image if ready
        if needNewImage:
          self.position['image'] += 1
          if self.position['image'] == self.numImages:
            self.position['image'] = 0

        # -----------------------------------------------------------------
        # Get the home position for this new filtered image
        self._getHomePosition()

    # ========================================================================
    # Get the X,Y corrdinates and reset signal
    if not seeking:
      self._getPosition()
コード例 #19
0
ファイル: SpiralSweep.py プロジェクト: ywcui1990/nupic.vision
    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
コード例 #20
0
  def next(self, seeking=False):
    """
    Go to the next position (next iteration).

    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()
コード例 #21
0
    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 = []
コード例 #22
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
コード例 #23
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
コード例 #24
0
ファイル: EyeMovements.py プロジェクト: CV-IP/nupic.vision
  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
コード例 #25
0
  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 = []
コード例 #26
0
ファイル: OnionBlock.py プロジェクト: jaredweiss/nupic.vision
 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
コード例 #27
0
ファイル: RandomJump.py プロジェクト: ywcui1990/nupic.vision
    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
コード例 #28
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
コード例 #29
0
  def first(self, seeking=False):
    """Used in initialization of ImageSensor.
    Basic setup for running sequential saccades on random images.

    :param seeking: If True, don't do unnecessary computations
    """
    if not self.numImages:
      return

    self.history = []
    self.imageHistory = []

    BaseExplorer.first(self)
    self.prevSaccade = None
    self.position["image"] = self.pickRandomImage(self.random)
    self.saccadeIndex = 0
コード例 #30
0
  def first(self, seeking=False):
    """Used in initialization of ImageSensor.
    Basic setup for running sequential saccades on random images.

    :param seeking: If True, don't do unnecessary computations
    """
    if not self.numImages:
      return

    self.history = []
    self.imageHistory = []

    BaseExplorer.first(self)
    self.prevSaccade = None
    self.position["image"] = self.pickRandomImage(self.random)
    self.saccadeIndex = 0
コード例 #31
0
ファイル: OnionSweep.py プロジェクト: jaredweiss/nupic.vision
  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.diagdiri = 0
    self.diagi = 0
    self.position['offset'][0] += self.numSteps
    self.cent = list(self.position['offset'])
    self.jitteri = 0
コード例 #32
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.diagdiri = 0
        self.diagi = 0
        self.position['offset'][0] += self.numSteps
        self.cent = list(self.position['offset'])
        self.jitteri = 0
コード例 #33
0
ファイル: SpiralSweep.py プロジェクト: ywcui1990/nupic.vision
    def first(self, center=True):
        """
    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)
        self._resetIndex()

        offsets = self._getCurrentOffsets()
        # Set the 2 dimensions of the position.
        for i in (0, 1):
            self.position['offset'][i] = offsets[self.index][i]
コード例 #34
0
ファイル: SpiralSweep.py プロジェクト: CV-IP/nupic.vision
  def first(self, center=True):
    """
    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)
    self._resetIndex()

    offsets = self._getCurrentOffsets()
    # Set the 2 dimensions of the position.
    for i in (0,1):
      self.position['offset'][i] = offsets[self.index][i]
コード例 #35
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)

        if not self.numImages:
            return

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

        while True:
            self.position['image'] = self.pickRandomImage(self.random)
            self.position['filters'] = self.pickRandomFilters(self.random)
            index = self.random.randint(0, 8)
            historyItem = (self.position['image'], self.position['filters'][:],
                           index)
            if self.replacement or historyItem not in self.history:
                # Use this position
                if not self.replacement:
                    # Add to the history
                    self.history.append(historyItem)
                # Calculate the offset from the eye movement index
                if index in (1, 2, 3):
                    self.position['offset'][1] -= self.shift
                elif index in (5, 6, 7):
                    self.position['offset'][1] += self.shift
                if index in (1, 7, 8):
                    self.position['offset'][0] -= self.shift
                elif index in (3, 4, 5):
                    self.position['offset'][0] += self.shift
                break

        self.position['reset'] = True
コード例 #36
0
ファイル: SpiralSweep.py プロジェクト: CV-IP/nupic.vision
  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
コード例 #37
0
ファイル: RandomJump.py プロジェクト: jaredweiss/nupic.vision
  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
コード例 #38
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)

    if not self.numImages:
      return

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

    while True:
      self.position['image'] = self.pickRandomImage(self.random)
      self.position['filters'] = self.pickRandomFilters(self.random)
      index = self.random.randint(0, 8)
      historyItem = (self.position['image'], self.position['filters'][:], index)
      if self.replacement or historyItem not in self.history:
        # Use this position
        if not self.replacement:
          # Add to the history
          self.history.append(historyItem)
        # Calculate the offset from the eye movement index
        if index in (1, 2, 3):
          self.position['offset'][1] -= self.shift
        elif index in (5, 6, 7):
          self.position['offset'][1] += self.shift
        if index in (1, 7, 8):
          self.position['offset'][0] -= self.shift
        elif index in (3, 4, 5):
          self.position['offset'][0] += self.shift
        break

    self.position['reset'] = True
コード例 #39
0
  def seek(self, iteration=None, position=None):
    """Seek to the specified position or iteration.

    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.

    :param iteration: Target iteration number (or None).
    :param position: Target position (or None).
    """

    # 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)
コード例 #40
0
  def seek(self, iteration=None, position=None):
    """Seek to the specified position or iteration.

    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.

    :param iteration: Target iteration number (or None).
    :param position: Target position (or None).
    """

    # 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)
コード例 #41
0
ファイル: RandomSweep.py プロジェクト: ywcui1990/nupic.vision
    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
コード例 #42
0
ファイル: RandomSweep.py プロジェクト: ywcui1990/nupic.vision
    def next(self, seeking=False):
        """
    Go to the next position (next iteration).

    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()
コード例 #43
0
ファイル: RandomFlash.py プロジェクト: numenta/nupic.vision
    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 = []
コード例 #44
0
  def next(self, seeking=False):
    """
    Go to the next position (next iteration).

    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()
コード例 #45
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)
コード例 #46
0
ファイル: ManualSaliency.py プロジェクト: CV-IP/nupic.vision
  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
コード例 #47
0
  def next(self, seeking=False):
    """Move to the next saccade position if number of saccades on an image
    has not reached it's maximum. Otherwise, load the next random image.

    :param seeking: If True, don't do unnecessary computations
    """
    if not self.numImages:
      return

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

    while True:
      if self.saccadeIndex is 0 or self.saccadeIndex > (self.numSaccades - 1):
        while self.position["image"] in self.imageHistory:
          BaseExplorer.first(self)
          self.position["image"] = self.pickRandomImage(self.random)
        self.imageHistory.append(self.position["image"])
        self.prevSaccade = {"prevOffset": deepcopy(self.position["offset"]),
                            "direction": None,
                            "length": None,
                            "newOffset": deepcopy(self.position["offset"])}
        historyItem = (self.position["image"],
                       self.saccadeIndex)
        if not self.replacement:
          # Add to the history
          self.history.append(historyItem)
        self.saccadeIndex = 1
        return

      if not seeking:
        saccadeDirection = self.random.choice(_DIRECTIONS)
        saccadeLength =  self.random.randint(self.saccadeMin, self.saccadeMax)

      historyItem = (self.position["image"],
                     self.saccadeIndex)
      if self.replacement or historyItem not in self.history:
        # Use this position
        if not seeking:
          imageSize = self.getFilteredImages()[0].size
          if not self._checkFoveaInImage(imageSize,
                                         saccadeLength,
                                         saccadeDirection):
            continue

          self.prevSaccade = {"prevOffset": deepcopy(self.position["offset"]),
                              "direction": saccadeDirection,
                              "length": saccadeLength}
          if saccadeDirection == "left":
            self.position["offset"][0] -= saccadeLength
          elif saccadeDirection == "right":
            self.position["offset"][0] += saccadeLength
          elif saccadeDirection == "up":
            self.position["offset"][1] -= saccadeLength
          elif saccadeDirection == "down":
            self.position["offset"][1] += saccadeLength
          self.prevSaccade["newOffset"] = deepcopy(self.position["offset"])


        if not self.replacement:
          # Add to the history
          self.history.append(historyItem)
        self.saccadeIndex += 1
        return
コード例 #48
0
ファイル: RandomSweep.py プロジェクト: ywcui1990/nupic.vision
    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 xrange(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(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(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(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], 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], 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(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], 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], 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
コード例 #49
0
ファイル: MultiSweep.py プロジェクト: CV-IP/nupic.vision
  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()
コード例 #50
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()
コード例 #51
0
ファイル: MultiSweep.py プロジェクト: CV-IP/nupic.vision
  def next(self, seeking=False):
    """
    Go to the next position (next iteration).

    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
      return
    self.position['reset'] = False

    prevPosition = self._copyPosition(self.position)

    # Translation sweep
    if self.dimension['name'] == 'translation':
      self._nextTranslationPosition()
      bounceDirections = self._getBounceDirections()
      while self.position['reset'] and self.length < self.minSweepLength and \
          bounceDirections:
        # Sweep is too short - bounce and continue
        self.position = self._copyPosition(prevPosition)
        self.direction = bounceDirections.pop(0)
        self._nextTranslationPosition()

    # Image sweep
    elif self.dimension['name'] == 'image':
      self._nextImagePosition()
      if self.position['reset'] and self.length < self.minSweepLength:
        # Sweep is too short - bounce and continue
        self.position = prevPosition
        if self.direction == 'up':
          self.direction = 'down'
        else:
          self.direction = 'up'
        self._nextImagePosition()

    # Parsed dimension sweep
    elif self.dimension['name'] in self.parsedDimensions:
      self._nextParsedPosition()
      if self.position['reset'] and self.length < self.minSweepLength:
        # Sweep is too short - bounce and continue
        self.position = prevPosition
        if self.direction == 'up':
          self.direction = 'down'
        else:
          self.direction = 'up'
        self._nextParsedPosition()

    # Filter sweep
    else:
      self._nextFilterPosition()
      if self.position['reset'] and self.length < self.minSweepLength:
        # Sweep is too short - bounce and continue
        self.position = prevPosition
        if self.direction == 'up':
          self.direction = 'down'
        else:
          self.direction = 'up'
        self._nextFilterPosition()

    # Stop the sweep if it has fallen off the object
    if not self.position['reset'] \
        and self.isBlank(self.dimension['sweepOffObject']):
      self.position['reset'] = True

    # Begin a new sweep if necessary
    if self.position['reset']:
      self.first()
    else:
      self.length += 1
コード例 #52
0
ファイル: MultiSweep.py プロジェクト: CV-IP/nupic.vision
  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 dimension (exclude filters without multiple outputs)
    filters = []
    for i in xrange(self.numFilters):
      if self.numFilterOutputs[i] > 1:
        filters.append(i)
    legalDimensions = self.dimensions[:]
    for d in self.dimensions:
      if type(d['name']) is int and d['name'] not in filters:
        legalDimensions.remove(d)
    # Choice is weighted by probabilities
    r = self.random.uniform(0, sum([d['probability'] for d in legalDimensions]))
    for i, d in enumerate(legalDimensions):
      if r <= d['probability']:
        self.dimension = d
        break
      r -= d['probability']

    self.start = None
    restart = True
    while restart:

      self.position['reset'] = False
      restart = False

      # Translation sweep
      if self.dimension['name'] == 'translation':

        # Pick a random direction, image, and set of filters
        self.direction = self.random.choice(('left', 'right', 'up', 'down',
          'leftdown', 'leftup', 'rightdown', 'rightup'))
        self.position['image'] = self.pickRandomImage(self.random)
        self.position['filters'] = self.pickRandomFilters(self.random)
        filteredImages = self.getFilteredImages()
        ebbox = self._getEffectiveBoundingBox(filteredImages[0])

        # Align starting position at zero offset position.
        forceAlignment = self.dimension.get('forceAlignment')
        if forceAlignment is not None and forceAlignment:
          self.position['offset'] = [0,0]
        # Pick a random starting position on the appropriate edge of the image
        else:
          self._firstTranslationPosition(ebbox, filteredImages[0])

        # Increment the start position until it is not blank
        while self.isBlank(self.dimension['sweepOffObject']):
          self._nextTranslationPosition(shift=1)
          if self.position['reset'] or not self.isValid():
            restart = True
            break
        if restart:
          continue

        # Increment the position by a random amount in the range [0, shift)
        if not forceAlignment:
          self._nextTranslationPosition(randomShift=True)

      # Image sweep
      elif self.dimension['name'] == 'image':

        # Pick a random direction
        self.direction = self.random.choice(('up', 'down'))

        # Pick a random image and find the first or last image in the category
        image = self.pickRandomImage(self.random)
        startCategory = self.getImageInfo(image)['categoryIndex']
        if self.direction == 'up':
          while image > 0 and \
              self.getImageInfo(image-1)['categoryIndex'] == startCategory:
            image -= 1
        else:
          while image < self.numImages - 1 and \
              self.getImageInfo(image+1)['categoryIndex'] == startCategory:
            image += 1
        self.position['image'] = image

        # Pick the filters
        self.position['filters'] = self.pickRandomFilters(self.random)
        filteredImages = self.getFilteredImages()

        # Pick a random position within the bounding box
        ebbox = self._getEffectiveBoundingBox(filteredImages[0])
        self.position['offset'] = [
          self.random.randint(ebbox[0], ebbox[2]-1),
          self.random.randint(ebbox[1], ebbox[3]-1)
        ]

        # Increment the start position until it is not blank
        while self.isBlank(self.dimension['sweepOffObject']):
          self._nextImagePosition(shift=1)
          if self.position['reset'] or not self.isValid():
            restart = True
            break
        if restart:
          continue

        # Increment the position by a random amount in the range [0, shift)
        self._nextImagePosition(randomShift=True)

      # Parsed dimension sweep
      elif self.dimension['name'] in self.parsedDimensions:

        # Pick a random direction
        self.direction = self.random.choice(('up', 'down'))

        # Pick a random image
        image = self.pickRandomImage(self.random)

        # Create a list of filenames that will be included in this sweep
        self._createParsedDimension(image)

        # Find the first or last image
        if self.direction == 'up':
          self.parsedIndex = 0
        else:
          self.parsedIndex = len(self.parsedIndices) - 1
        self.position['image'] = self.parsedIndices[self.parsedIndex]

        # Pick the filters
        self.position['filters'] = self.pickRandomFilters(self.random)
        filteredImages = self.getFilteredImages()

        # Pick a random position within the bounding box
        ebbox = self._getEffectiveBoundingBox(filteredImages[0])
        self.position['offset'] = [
          self.random.randint(ebbox[0], ebbox[2]-1),
          self.random.randint(ebbox[1], ebbox[3]-1)
        ]

        # Increment the start position until it is not blank
        while self.isBlank(self.dimension['sweepOffObject']):
          self._nextParsedPosition(shift=1)
          if self.position['reset'] or not self.isValid():
            restart = True
            break
        if restart:
          continue

        # Increment the position by a random amount in the range [0, shift)
        self._nextParsedPosition(randomShift=True)

      # Filter sweep
      else:

        # Pick a random direction, image, and set of filters
        self.direction = self.random.choice(('up', 'down'))
        self.position['image'] = self.pickRandomImage(self.random)
        self.position['filters'] = self.pickRandomFilters(self.random)
        filteredImages = self.getFilteredImages()

        # Go to one end of the selected filter
        if self.direction == 'up':
          self.position['filters'][self.dimension['name']] = 0
        else:
          self.position['filters'][self.dimension['name']] = \
            self.numFilterOutputs[self.dimension['name']] - 1

        # Pick a random position within the bounding box
        filteredImages = self.getFilteredImages()
        ebbox = self._getEffectiveBoundingBox(filteredImages[0])
        self.position['offset'] = [
          self.random.randint(ebbox[0], ebbox[2]-1),
          self.random.randint(ebbox[1], ebbox[3]-1)
        ]
        self.prevImageSize = filteredImages[0].size

        # Increment the start position until it is not blank
        while self.isBlank(self.dimension['sweepOffObject']):
          self._nextFilterPosition(shift=1)
          if self.position['reset'] or not self.isValid():
            restart = True
            break
        if restart:
          continue

        # Increment the position by a random amount in the range [0, shift)
        self._nextFilterPosition(randomShift=True)

    self.start = self._copyPosition(self.position)
    self.position['reset'] = True
    self.length = 1
コード例 #53
0
    def next(self, seeking=False):
        """
    Go to the next position (next iteration).

    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
            return
        self.position['reset'] = False

        prevPosition = self._copyPosition(self.position)

        # Translation sweep
        if self.dimension['name'] == 'translation':
            self._nextTranslationPosition()
            bounceDirections = self._getBounceDirections()
            while self.position['reset'] and self.length < self.minSweepLength and \
                bounceDirections:
                # Sweep is too short - bounce and continue
                self.position = self._copyPosition(prevPosition)
                self.direction = bounceDirections.pop(0)
                self._nextTranslationPosition()

        # Image sweep
        elif self.dimension['name'] == 'image':
            self._nextImagePosition()
            if self.position['reset'] and self.length < self.minSweepLength:
                # Sweep is too short - bounce and continue
                self.position = prevPosition
                if self.direction == 'up':
                    self.direction = 'down'
                else:
                    self.direction = 'up'
                self._nextImagePosition()

        # Parsed dimension sweep
        elif self.dimension['name'] in self.parsedDimensions:
            self._nextParsedPosition()
            if self.position['reset'] and self.length < self.minSweepLength:
                # Sweep is too short - bounce and continue
                self.position = prevPosition
                if self.direction == 'up':
                    self.direction = 'down'
                else:
                    self.direction = 'up'
                self._nextParsedPosition()

        # Filter sweep
        else:
            self._nextFilterPosition()
            if self.position['reset'] and self.length < self.minSweepLength:
                # Sweep is too short - bounce and continue
                self.position = prevPosition
                if self.direction == 'up':
                    self.direction = 'down'
                else:
                    self.direction = 'up'
                self._nextFilterPosition()

        # Stop the sweep if it has fallen off the object
        if not self.position['reset'] \
            and self.isBlank(self.dimension['sweepOffObject']):
            self.position['reset'] = True

        # Begin a new sweep if necessary
        if self.position['reset']:
            self.first()
        else:
            self.length += 1
コード例 #54
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
コード例 #55
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 dimension (exclude filters without multiple outputs)
        filters = []
        for i in xrange(self.numFilters):
            if self.numFilterOutputs[i] > 1:
                filters.append(i)
        legalDimensions = self.dimensions[:]
        for d in self.dimensions:
            if type(d['name']) is int and d['name'] not in filters:
                legalDimensions.remove(d)
        # Choice is weighted by probabilities
        r = self.random.uniform(
            0, sum([d['probability'] for d in legalDimensions]))
        for i, d in enumerate(legalDimensions):
            if r <= d['probability']:
                self.dimension = d
                break
            r -= d['probability']

        self.start = None
        restart = True
        while restart:

            self.position['reset'] = False
            restart = False

            # Translation sweep
            if self.dimension['name'] == 'translation':

                # Pick a random direction, image, and set of filters
                self.direction = self.random.choice(
                    ('left', 'right', 'up', 'down', 'leftdown', 'leftup',
                     'rightdown', 'rightup'))
                self.position['image'] = self.pickRandomImage(self.random)
                self.position['filters'] = self.pickRandomFilters(self.random)
                filteredImages = self.getFilteredImages()
                ebbox = self._getEffectiveBoundingBox(filteredImages[0])

                # Align starting position at zero offset position.
                forceAlignment = self.dimension.get('forceAlignment')
                if forceAlignment is not None and forceAlignment:
                    self.position['offset'] = [0, 0]
                # Pick a random starting position on the appropriate edge of the image
                else:
                    self._firstTranslationPosition(ebbox, filteredImages[0])

                # Increment the start position until it is not blank
                while self.isBlank(self.dimension['sweepOffObject']):
                    self._nextTranslationPosition(shift=1)
                    if self.position['reset'] or not self.isValid():
                        restart = True
                        break
                if restart:
                    continue

                # Increment the position by a random amount in the range [0, shift)
                if not forceAlignment:
                    self._nextTranslationPosition(randomShift=True)

            # Image sweep
            elif self.dimension['name'] == 'image':

                # Pick a random direction
                self.direction = self.random.choice(('up', 'down'))

                # Pick a random image and find the first or last image in the category
                image = self.pickRandomImage(self.random)
                startCategory = self.getImageInfo(image)['categoryIndex']
                if self.direction == 'up':
                    while image > 0 and \
                        self.getImageInfo(image-1)['categoryIndex'] == startCategory:
                        image -= 1
                else:
                    while image < self.numImages - 1 and \
                        self.getImageInfo(image+1)['categoryIndex'] == startCategory:
                        image += 1
                self.position['image'] = image

                # Pick the filters
                self.position['filters'] = self.pickRandomFilters(self.random)
                filteredImages = self.getFilteredImages()

                # Pick a random position within the bounding box
                ebbox = self._getEffectiveBoundingBox(filteredImages[0])
                self.position['offset'] = [
                    self.random.randint(ebbox[0], ebbox[2] - 1),
                    self.random.randint(ebbox[1], ebbox[3] - 1)
                ]

                # Increment the start position until it is not blank
                while self.isBlank(self.dimension['sweepOffObject']):
                    self._nextImagePosition(shift=1)
                    if self.position['reset'] or not self.isValid():
                        restart = True
                        break
                if restart:
                    continue

                # Increment the position by a random amount in the range [0, shift)
                self._nextImagePosition(randomShift=True)

            # Parsed dimension sweep
            elif self.dimension['name'] in self.parsedDimensions:

                # Pick a random direction
                self.direction = self.random.choice(('up', 'down'))

                # Pick a random image
                image = self.pickRandomImage(self.random)

                # Create a list of filenames that will be included in this sweep
                self._createParsedDimension(image)

                # Find the first or last image
                if self.direction == 'up':
                    self.parsedIndex = 0
                else:
                    self.parsedIndex = len(self.parsedIndices) - 1
                self.position['image'] = self.parsedIndices[self.parsedIndex]

                # Pick the filters
                self.position['filters'] = self.pickRandomFilters(self.random)
                filteredImages = self.getFilteredImages()

                # Pick a random position within the bounding box
                ebbox = self._getEffectiveBoundingBox(filteredImages[0])
                self.position['offset'] = [
                    self.random.randint(ebbox[0], ebbox[2] - 1),
                    self.random.randint(ebbox[1], ebbox[3] - 1)
                ]

                # Increment the start position until it is not blank
                while self.isBlank(self.dimension['sweepOffObject']):
                    self._nextParsedPosition(shift=1)
                    if self.position['reset'] or not self.isValid():
                        restart = True
                        break
                if restart:
                    continue

                # Increment the position by a random amount in the range [0, shift)
                self._nextParsedPosition(randomShift=True)

            # Filter sweep
            else:

                # Pick a random direction, image, and set of filters
                self.direction = self.random.choice(('up', 'down'))
                self.position['image'] = self.pickRandomImage(self.random)
                self.position['filters'] = self.pickRandomFilters(self.random)
                filteredImages = self.getFilteredImages()

                # Go to one end of the selected filter
                if self.direction == 'up':
                    self.position['filters'][self.dimension['name']] = 0
                else:
                    self.position['filters'][self.dimension['name']] = \
                      self.numFilterOutputs[self.dimension['name']] - 1

                # Pick a random position within the bounding box
                filteredImages = self.getFilteredImages()
                ebbox = self._getEffectiveBoundingBox(filteredImages[0])
                self.position['offset'] = [
                    self.random.randint(ebbox[0], ebbox[2] - 1),
                    self.random.randint(ebbox[1], ebbox[3] - 1)
                ]
                self.prevImageSize = filteredImages[0].size

                # Increment the start position until it is not blank
                while self.isBlank(self.dimension['sweepOffObject']):
                    self._nextFilterPosition(shift=1)
                    if self.position['reset'] or not self.isValid():
                        restart = True
                        break
                if restart:
                    continue

                # Increment the position by a random amount in the range [0, shift)
                self._nextFilterPosition(randomShift=True)

        self.start = self._copyPosition(self.position)
        self.position['reset'] = True
        self.length = 1