def __init__(self, value_mapping, colour_mapping): """Construct an `ObservationToArrayWithRGB`. Builds a callable that will take `Observation`s and emit a dictionary containing a 2-D and 3-D numpy array. The rows and columns of the 2-D array contain the values obtained after mapping the characters of the original `Observation` through `value_mapping`. The rows and columns of the 3-D array contain RGB values of the previous 2-D mapping in the [0,1] range. Args: value_mapping: a dict mapping any characters that might appear in the original `Observation`s to a scalar or 1-D vector value. All values in this dict must be the same type and dimension. Note that strings are considered 1-D vectors, not scalar values. colour_mapping: a dict mapping any characters that might appear in the original `Observation`s to a 3-tuple of RGB values in the range [0,999]. """ self._value_mapping = value_mapping self._colour_mapping = colour_mapping # Rendering functions for the `board` representation and `RGB` values. self._renderers = { 'board': rendering.ObservationToArray(value_mapping=value_mapping, dtype=np.float32), # RGB should be np.uint8, but that will be applied in __call__, # since values here are outside of uint8 range. 'RGB': rendering.ObservationToArray(value_mapping=colour_mapping) }
def __init__(self, game, num_apples=10, apple_reward=1., fix_apple_reward_in_episode=False, final_reward=10., crop=True, default_reward=0): """Construct a `environment.Base` adapter that wraps a pycolab game.""" rng = np.random.RandomState() if game == 'key_to_door': self._game = key_to_door.Game(rng, num_apples, apple_reward, fix_apple_reward_in_episode, final_reward, crop) elif game == 'active_visual_match': self._game = active_visual_match.Game(rng, num_apples, apple_reward, fix_apple_reward_in_episode, final_reward) else: raise ValueError('Unsupported game "%s".' % game) self._default_reward = default_reward self._num_actions = self._game.num_actions # Agents expect HWC uint8 observations, Pycolab uses CHW float observations. #colours = nest.map_structure(lambda c: float(c) * 255 / 1000, # self._game.colours) colours = tf.nest.map_structure(lambda c: float(c) * 255 / 1000, self._game.colours) self._rgb_converter = rendering.ObservationToArray( value_mapping=colours, permute=(1, 2, 0), dtype=np.uint8) episode = self._game.make_episode() observation, _, _ = episode.its_showtime() self._image_shape = self._rgb_converter(observation).shape
def renderer(obs, scale=8): renderer_normal = rendering.ObservationToArray(COLOR_MAP, dtype=np.float32) obs_normal = renderer_normal(obs) obs_normal = trans_image(obs_normal) new_size = obs_normal.shape[1] * scale # Scale up the observation. scaled_img = np.stack([ scipy.misc.imresize(obs_normal[:, :, i], [new_size, new_size, 1], interp="nearest") for i in range(3) ], axis=2) return np.transpose(scaled_img, (2, 1, 0))
def testRendering(self): """Test various rendering utilities.""" # This helper will allow us to compare numpy bool_ arrays with "art" drawn # as lists of '0' and '1' characters. def assertMask(actual_mask, mask_art, err_msg=''): # pylint: disable=invalid-name np.testing.assert_array_equal( actual_mask, np.array([list(row) for row in mask_art]).astype(bool), err_msg) # Our test concerns renderings of this game world. art = ['..H..H..o..', '..HHHH..i..', '..H..H..i..'] # Here we make the game. Note specification of Q, an empty Drape. engine = ascii_art.ascii_art_to_game(art=art, what_lies_beneath='.', drapes=dict(Q=tt.TestDrape)) ### GAME ITERATION 0. We just run it to get an observation. observation, unused_reward, unused_discount = engine.its_showtime() ### Evaluate the observation's binary feature masks. # The observation's layer member should have an entry for all characters # that could be on the board, including ones for invisible Drapes. self.assertEqual(sorted(observation.layers.keys()), sorted(list('.HioQ'))) # Check that all the layer masks have the right contents. assertMask(observation.layers['.'], ['11011011011', '11000011011', '11011011011']) assertMask(observation.layers['H'], ['00100100000', '00111100000', '00100100000']) assertMask(observation.layers['i'], ['00000000000', '00000000100', '00000000100']) assertMask(observation.layers['o'], ['00000000100', '00000000000', '00000000000']) assertMask(observation.layers['Q'], ['00000000000', '00000000000', '00000000000']) ### Test correct operation of ObservationCharacterRepainter. repainter = rendering.ObservationCharacterRepainter( dict(H='J', i='J', Q='M')) repainted = repainter(observation) # Check that the repainted board looks correct. self.assertBoard(repainted.board, ['..J..J..o..', '..JJJJ..J..', '..J..J..J..']) # The repainted board should have these binary feature masks: self.assertEqual(sorted(repainted.layers.keys()), sorted(list('.JoM'))) # The binary feature masks should have these contents: assertMask(repainted.layers['.'], ['11011011011', '11000011011', '11011011011']) assertMask(repainted.layers['J'], ['00100100000', '00111100100', '00100100100']) assertMask(repainted.layers['o'], ['00000000100', '00000000000', '00000000000']) assertMask(repainted.layers['M'], ['00000000000', '00000000000', '00000000000']) ### Test correct operation of ObservationToArray for 2-D and 3-D arrays. # For the 2-D conversion, we'll do our own "homebrew" repainter, but just # for the Observation.board representation. Recall that the board member of # an Observation is a 2-D array of uint8s. converter = rendering.ObservationToArray( { '.': ord(' '), 'J': ord('#'), 'o': ord('*'), 'M': ord('?') }, dtype=np.uint8) converted = converter(repainted) self.assertBoard(converted, [' # # * ', ' #### # ', ' # # # ']) # Test that layer permutation happens correctly for the 2-D case. converter = rendering.ObservationToArray( { '.': ord(' '), 'J': ord('#'), 'o': ord('*'), 'M': ord('?') }, dtype=np.uint8, permute=(1, 0)) converted = converter(repainted) self.assertBoard(converted, [ ' ', ' ', '###', ' # ', ' # ', '###', ' ', ' ', '*##', ' ', ' ' ]) # For the 3-D conversion, we'll create a 3-D feature array that's a lot like # our feature masks. converter = rendering.ObservationToArray( { '.': (1, 0, 0, 0), 'J': (0, 1, 0, 0), 'o': (0, 0, 1, 0), 'M': (0, 0, 0, 1) }, dtype=bool) converted = converter(repainted) self.assertEqual(converted.shape, (4, 3, 11)) assertMask(converted[0, :], ['11011011011', '11000011011', '11011011011']) assertMask(converted[1, :], ['00100100000', '00111100100', '00100100100']) assertMask(converted[2, :], ['00000000100', '00000000000', '00000000000']) assertMask(converted[3, :], ['00000000000', '00000000000', '00000000000']) # And another layer permutation test for the 3-D case. converter = rendering.ObservationToArray( { '.': (1, 0, 0, 0), 'J': (0, 1, 0, 0), 'o': (0, 0, 1, 0), 'M': (0, 0, 0, 1) }, dtype=bool, permute=(1, 2, 0)) converted = converter(repainted) self.assertEqual(converted.shape, (3, 11, 4)) assertMask(converted[..., 0], ['11011011011', '11000011011', '11011011011']) assertMask(converted[..., 1], ['00100100000', '00111100100', '00100100100']) assertMask(converted[..., 2], ['00000000100', '00000000000', '00000000000']) assertMask(converted[..., 3], ['00000000000', '00000000000', '00000000000']) ### Test ObservationToFeatureArray, which creates 3-D feature arrays faster. converter = rendering.ObservationToFeatureArray('.JoM') converted = converter(repainted) self.assertEqual(converted.shape, (4, 3, 11)) assertMask(converted[0, :], ['11011011011', '11000011011', '11011011011']) assertMask(converted[1, :], ['00100100000', '00111100100', '00100100100']) assertMask(converted[2, :], ['00000000100', '00000000000', '00000000000']) assertMask(converted[3, :], ['00000000000', '00000000000', '00000000000']) ### Test ObservationToFeatureArray's layer permutation capability. converter = rendering.ObservationToFeatureArray('.J', permute=(1, 0, 2)) converted = converter(repainted) self.assertEqual(converted.shape, (3, 2, 11)) assertMask(converted[0, :], ['11011011011', '00100100000']) assertMask(converted[1, :], ['11000011011', '00111100100']) assertMask(converted[2, :], ['11011011011', '00100100100'])
def converter(obs): converter = rendering.ObservationToArray(COLOUR_FG, permute=(0, 1, 2)) converted = np.swapaxes(converter(obs), 1, 2).T return converted