Example #1
0
 def __init__(self, imageSize=default_image_size, timeNow=0.0):
   # * Initialize members, parameters
   self.context = Context.getInstance()
   self.logger = logging.getLogger(__name__)
   self.logger.debug("Creating simplified Retina")  # to distinguish from other Retina versions
   self.imageSize = imageSize
   self.imageCenter = (self.imageSize[1] / 2, self.imageSize[0] / 2)
   self.timeNow = timeNow
   self.bounds = np.float32([[0.0, 0.0, 2.0], [self.imageSize[0] - 1, self.imageSize[1] - 1, 4.0]])
   self.center = (self.bounds[0] + self.bounds[1]) / 2
   self.logger.debug("Retina center: {}, image size: {}".format(self.center, self.imageSize))
   
   self.bipolarBlurSize = (5, 5)  # size of blurring kernel used when computing Bipolar cell response
   self.ganglionCenterSurroundKernel = np.float32(
     [ [ -1, -1, -1, -1, -1, -1, -1 ],
       [ -1, -1, -1, -1, -1, -1, -1 ],
       [ -1, -1,  7,  7,  7, -1, -1 ],
       [ -1, -1,  7,  9,  7, -1, -1 ],
       [ -1, -1,  7,  7,  7, -1, -1 ],
       [ -1, -1, -1, -1, -1, -1, -1 ],
       [ -1, -1, -1, -1, -1, -1, -1 ] ])
   self.ganglionCenterSurroundKernel /= np.sum(self.ganglionCenterSurroundKernel)  # normalize
   #self.logger.info("Ganglion center-surround kernel:\n{}".format(self.ganglionCenterSurroundKernel))  # [debug]
   self.ganglionKernelLevels = 4
   self.ganglionKernels = [None] * self.ganglionKernelLevels
   self.ganglionKernels[0] = self.ganglionCenterSurroundKernel
   for i in xrange(1, self.ganglionKernelLevels):
     self.ganglionKernels[i] = cv2.resize(self.ganglionKernels[i - 1], dsize=None, fx=2, fy=2)
     self.ganglionKernels[i] /= np.sum(self.ganglionKernels[i])  # normalize
   #self.logger.info("Ganglion center-surround kernel sizes ({} levels): {}".format(self.ganglionKernelLevels, ", ".join("{}".format(k.shape) for k in self.ganglionKernels)))  # [debug]
   
   # * Image and related members
   self.imageCenter = (self.imageSize[1] / 2, self.imageSize[0] / 2)
   self.imageShapeC3 = (self.imageSize[1], self.imageSize[0], 3)  # numpy shape for 3 channel images
   self.imageShapeC1 = (self.imageSize[1], self.imageSize[0])  # numpy shape for single channel images
   # NOTE Image shapes (h, w, 1) and (h, w) are not compatible unless we use keepdims=True for numpy operations
   self.imageTypeInt = np.uint8  # numpy dtype for integer-valued images
   self.imageTypeFloat = np.float32  # numpy dtype for real-valued images
   self.images = OrderedDict()
   
   # ** RGB and HSV images
   self.images['BGR'] = np.zeros(self.imageShapeC3, dtype=self.imageTypeInt)
   self.images['HSV'] = np.zeros(self.imageShapeC3, dtype=self.imageTypeInt)
   self.images['H'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeInt)
   self.images['S'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeInt)
   self.images['V'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeInt)
   
   # ** Freq/hue-dependent response images for rods and different cone types
   self.imageRod = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   self.imagesCone = dict()  # NOTE dict keys must match names of Cone.cone_types
   self.imagesCone['S'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   self.imagesCone['M'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   self.imagesCone['L'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   
   # ** Bipolar and Ganglion cell response images
   # TODO Add more Ganglion cell types with different receptive field properties (color-opponent cells)
   #   'RG' +Red    -Green
   #   'GR' +Green  -Red
   #   'RB' +Red    -Blue
   #   'BR' +Blue   -Red
   #   'BY' +Blue   -Yellow
   #   'YB' +Yellow -Blue
   #   'WK' +White  -Black (currently 'ON')
   #   'KW' +Black  -White (currently 'OFF')
   # NOTE: R = L cones, G = M cones, B = S cones
   self.imagesBipolar = dict()
   self.imagesBipolar['ON'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   self.imagesBipolar['OFF'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   self.imagesGanglion = dict()
   self.imagesGanglion['ON'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   self.imagesGanglion['OFF'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   # TODO Verify why image shapes (h, w, 1) and (h, w) are not compatible (use keepdims=True for numpy operations)
   self.imagesGanglion['RG'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   self.imagesGanglion['GR'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   self.imagesGanglion['RB'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   self.imagesGanglion['BR'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   self.imagesGanglion['BY'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   self.imagesGanglion['YB'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   
   # ** Combined response (salience) image
   self.imageSalience = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   
   # ** Spatial attention map with a central (covert) spotlight (currently unused; TODO move to VisualCortex? also, use np.ogrid?)
   self.imageAttention = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   cv2.circle(self.imageAttention, (self.imageSize[1] / 2, self.imageSize[0] / 2), self.imageSize[0] / 3, 1.0, cv.CV_FILLED)
   self.imageAttention = cv2.blur(self.imageAttention, (self.imageSize[0] / 4, self.imageSize[0] / 4))  # coarse blur
   
   # ** Output image(s)
   if self.context.options.gui:
     self.imageOut = np.zeros(self.imageShapeC3, dtype=self.imageTypeInt)
Example #2
0
 def __init__(self, imageSize=default_image_size, timeNow=0.0):
   # * Initialize members, parameters
   self.context = Context.getInstance()
   self.logger = logging.getLogger(__name__)
   self.imageSize = imageSize
   self.timeNow = timeNow
   self.bounds = np.float32([[0.0, 0.0, 2.0], [self.imageSize[0] - 1, self.imageSize[1] - 1, 4.0]])
   self.center = (self.bounds[0] + self.bounds[1]) / 2
   self.logger.debug("Retina center: {}, image size: {}".format(self.center, self.imageSize))
   self.rodDistribution = SymmetricLogNormal(mu=5.0, sigma=0.5, center=self.center)
   self.rodPlotColor = 'darkmagenta'
   self.coneDistribution = MultivariateNormal(mu=self.center, cov=(np.float32([1000.0, 1000.0, 1.0]) * np.identity(3, dtype=np.float32)))
   # TODO Create cone populations of different types with their respective spatial distributions (e.g. blue cones are mostly spread out)
   self.conePlotColor = 'darkgreen'
   self.conePlotColorsByType = [hsv_to_rgb(np.float32([[[coneType.hueResponse.mu / 180.0, 1.0, 1.0]]]))[0, 0] for coneType in Cone.cone_types]
   self.bipolarCellDistribution = MultivariateNormal(mu=self.center + np.float32([0.0, 0.0, 10.0]), cov=(np.float32([16000.0, 16000.0, 1.0]) * np.identity(3, dtype=np.float32)))
   self.bipolarCellPlotColor = 'orange'
   
   # * Image and related members
   self.imageCenter = (self.imageSize[1] / 2, self.imageSize[0] / 2)
   self.imageShapeC3 = (self.imageSize[1], self.imageSize[0], 3)  # numpy shape for 3 channel images
   self.imageShapeC1 = (self.imageSize[1], self.imageSize[0])  # numpy shape for single channel images
   # NOTE Image shapes (h, w, 1) and (h, w) are not compatible unless we use keepdims=True for numpy operations
   self.imageTypeInt = np.uint8  # numpy dtype for integer-valued images
   self.imageTypeFloat = np.float32  # numpy dtype for real-valued images
   self.images = OrderedDict()
   
   # ** RGB and HSV images
   self.images['BGR'] = np.zeros(self.imageShapeC3, dtype=self.imageTypeInt)
   self.images['HSV'] = np.zeros(self.imageShapeC3, dtype=self.imageTypeInt)
   self.images['H'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeInt)
   self.images['S'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeInt)
   self.images['V'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeInt)
   
   # ** Freq/hue-dependent response images for rods and different cone types
   self.imageRod = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   self.imagesCone = dict()  # NOTE dict keys must match names of Cone.cone_types
   self.imagesCone['S'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   self.imagesCone['M'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   self.imagesCone['L'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeFloat)
   
   # ** Output image(s)
   self.imageOut = None
   if self.context.options.gui:
     self.imageOut = np.zeros(self.imageShapeC3, dtype=self.imageTypeInt)
     self.imagesBipolar = dict()
     self.imagesBipolar['ON'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeInt)
     self.imagesBipolar['OFF'] = np.zeros(self.imageShapeC1, dtype=self.imageTypeInt)
   
   # * Create neuron populations
   # ** Photoreceptors
   self.rods = Population(numNeurons=self.num_rods, timeNow=self.timeNow, neuronTypes=[Rod], bounds=self.bounds, distribution=self.rodDistribution, retina=self)
   self.cones = Population(numNeurons=self.num_cones, timeNow=self.timeNow, neuronTypes=[Cone], bounds=self.bounds, distribution=self.coneDistribution, retina=self)
   self.coneTypeNames = [coneType.name for coneType in Cone.cone_types]  # mainly for plotting
   
   # ** Bipolar cells
   self.bipolarCells = Population(numNeurons=self.num_bipolar_cells, timeNow=self.timeNow, neuronTypes=[BipolarCell], bounds=self.bounds, distribution=self.bipolarCellDistribution, retina=self)
   
   # * Connect neuron populations
   growthConeDirection = self.bipolarCells.distribution.mu - self.cones.distribution.mu  # NOTE only using cone distribution center
   growthConeDirection /= np.linalg.norm(growthConeDirection, ord=2)  # need a unit vector
   self.cones.connectWith(self.bipolarCells, maxConnectionsPerNeuron=10, growthCone=GrowthCone(growthConeDirection, spreadFactor=1))
   self.rods.connectWith(self.bipolarCells, maxConnectionsPerNeuron=25, growthCone=GrowthCone(growthConeDirection, spreadFactor=1))