From e6d3f7ed1902c9642967c595ecb5d4863825a1de Mon Sep 17 00:00:00 2001 From: "Egli Adrian (IT-SCI-API-PFI)" <adrian.egli@sbb.ch> Date: Wed, 24 Jul 2019 15:11:05 +0200 Subject: [PATCH] #119 prediction rendering --- flatland/utils/graphics_pil.py | 15 ++++++- flatland/utils/rendertools.py | 13 ++++-- notebooks/Scene_Editor.ipynb | 50 ++++++++++++++++++++--- notebooks/Simple_Rendering_Demo.ipynb | 59 +++++++++++++++++---------- 4 files changed, 106 insertions(+), 31 deletions(-) diff --git a/flatland/utils/graphics_pil.py b/flatland/utils/graphics_pil.py index cf91cd6..d56055e 100644 --- a/flatland/utils/graphics_pil.py +++ b/flatland/utils/graphics_pil.py @@ -411,11 +411,13 @@ class PILSVG(PILGL): "NN SS": "Bahnhof_#d50000_Gleis_vertikal.svg"} # Dict of rail cell images indexed by binary transitions + pil_rail_files_org = self.load_svgs(rail_files, rotate=True) pil_rail_files = self.load_svgs(rail_files, rotate=True, background_image="Background_rail.svg", whitefilter="Background_white_filter.svg") # Load the target files (which have rails and transitions of their own) # They are indexed by (binTrans, iAgent), ie a tuple of the binary transition and the agent index + pil_target_files_org = self.load_svgs(target_files, rotate=False, agent_colors=self.agent_colors) pil_target_files = self.load_svgs(target_files, rotate=False, agent_colors=self.agent_colors, background_image="Background_rail.svg", whitefilter="Background_white_filter.svg") @@ -430,6 +432,7 @@ class PILSVG(PILGL): # Merge them with the regular rails. # https://stackoverflow.com/questions/38987/how-to-merge-two-dictionaries-in-a-single-expression self.pil_rail = {**pil_rail_files, **pil_target_files} + self.pil_rail_org = {**pil_rail_files_org, **pil_target_files_org} def load_svgs(self, file_directory, rotate=False, agent_colors=False, background_image=None, whitefilter=None): pil = {} @@ -482,9 +485,19 @@ class PILSVG(PILGL): return pil - def set_rail_at(self, row, col, binary_trans, target=None, is_selected=False, rail_grid=None): + def set_rail_at(self, row, col, binary_trans, target=None, is_selected=False, rail_grid=None, + agent_rail_color=None, blend_factor=0.5): if binary_trans in self.pil_rail: pil_track = self.pil_rail[binary_trans] + if agent_rail_color is not None: + colored_rail = self.recolor_image(self.pil_rail_org[binary_trans], [61, 61, 61], [agent_rail_color], False)[0] + rcTopLeft1 = (row, col) + rcTopLeft2 = (row + 1, col + 1) + rcTopLeft1 = tuple((array(rcTopLeft1) * self.nPixCell)[[1, 0]]) + rcTopLeft2 = tuple((array(rcTopLeft2) * self.nPixCell)[[1, 0]]) + pil_track = Image.blend(self.layers[0].crop((rcTopLeft1[0], rcTopLeft1[1], rcTopLeft2[0], rcTopLeft2[1])), colored_rail, + blend_factor) + if target is not None: pil_track = Image.alpha_composite(pil_track, self.station_colors[target % len(self.station_colors)]) diff --git a/flatland/utils/rendertools.py b/flatland/utils/rendertools.py index 4cac5ed..9f1b59e 100644 --- a/flatland/utils/rendertools.py +++ b/flatland/utils/rendertools.py @@ -276,7 +276,6 @@ class RenderTool(object): """ rt = self.__class__ - for agent in agent_handles: color = self.gl.get_agent_color(agent) for visited_cell in observation_dict[agent]: @@ -293,14 +292,20 @@ class RenderTool(object): """ rt = self.__class__ - for agent in agent_handles: color = self.gl.get_agent_color(agent) for visited_cell in prediction_dict[agent]: cell_coord = array(visited_cell[:2]) cell_coord_trans = np.matmul(cell_coord, rt.row_col_to_xy) + rt.x_y_half - self._draw_square(cell_coord_trans, 1 / (agent + 1.1), color, layer=1, opacity=100) - # TODO : Track highlighting (Adrian) + if type(self.gl) is PILSVG: + # TODO : Track highlighting (Adrian) + r = cell_coord[0] + c = cell_coord[1] + transitions = self.env.rail.grid[r, c] + self.gl.set_rail_at(r, c, transitions, target=None, is_selected=False, rail_grid=self.env.rail.grid, + agent_rail_color=color) + else: + self._draw_square(cell_coord_trans, 1 / (agent + 1.1), color, layer=1, opacity=100) def render_rail(self, spacing=False, rail_color="gray", curves=True, arrows=False): diff --git a/notebooks/Scene_Editor.ipynb b/notebooks/Scene_Editor.ipynb index 9ed6baf..acf418e 100644 --- a/notebooks/Scene_Editor.ipynb +++ b/notebooks/Scene_Editor.ipynb @@ -9,9 +9,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "<style>.container { width:95% !important; }</style>" + ], + "text/plain": [ + "<IPython.core.display.HTML object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "from IPython.core.display import display, HTML\n", "display(HTML(\"<style>.container { width:95% !important; }</style>\"))" @@ -19,7 +32,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -49,11 +62,38 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "scrolled": false }, - "outputs": [], + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "84809032a2f84b908e889f90594b3d62", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(Canvas(), VBox(children=(Text(value='temp.pkl', description='Filename'), Button(description='Re…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "load file: temp.pkl\n", + "Regenerate size 5 5\n", + "load file: temp.pkl\n", + "load file: temp.pkl\n", + "Regenerate size 5 5\n", + "load file: temp.pkl\n" + ] + } + ], "source": [ "mvc.view.display()" ] diff --git a/notebooks/Simple_Rendering_Demo.ipynb b/notebooks/Simple_Rendering_Demo.ipynb index 11cfb9d..5a3f4a4 100644 --- a/notebooks/Simple_Rendering_Demo.ipynb +++ b/notebooks/Simple_Rendering_Demo.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -19,7 +19,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -31,7 +31,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -41,7 +41,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -53,9 +53,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "<style>.container { width:90% !important; }</style>" + ], + "text/plain": [ + "<IPython.core.display.HTML object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "from IPython.core.display import display, HTML\n", "display(HTML(\"<style>.container { width:90% !important; }</style>\"))" @@ -70,7 +83,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -92,9 +105,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "ValueError", + "evalue": "images do not match", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m<ipython-input-7-5e6388f30b6b>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0moRT\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mrt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mRenderTool\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0menv\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mgl\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m\"PILSVG\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[0moRT\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrender_env\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0mimg\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0moRT\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget_image\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;32mc:\\users\\u216993\\appdata\\local\\programs\\python\\python36\\lib\\site-packages\\flatland_rl-0.2.0-py3.6.egg\\flatland\\utils\\rendertools.py\u001b[0m in \u001b[0;36mget_image\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 418\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 419\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mget_image\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 420\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgl\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget_image\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 421\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 422\u001b[0m def render_env_pil(self,\n", + "\u001b[1;32mc:\\users\\u216993\\appdata\\local\\programs\\python\\python36\\lib\\site-packages\\flatland_rl-0.2.0-py3.6.egg\\flatland\\utils\\graphics_pil.py\u001b[0m in \u001b[0;36mget_image\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 216\u001b[0m \u001b[1;32mwith\u001b[0m \u001b[0mlayer\u001b[0m \u001b[1;36m0\u001b[0m \u001b[0mat\u001b[0m \u001b[0mthe\u001b[0m \u001b[1;34m\"back\"\u001b[0m\u001b[1;33m.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 217\u001b[0m \"\"\"\n\u001b[1;32m--> 218\u001b[1;33m \u001b[0mimg\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0malpha_composite_layers\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 219\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0marray\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mimg\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 220\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mc:\\users\\u216993\\appdata\\local\\programs\\python\\python36\\lib\\site-packages\\flatland_rl-0.2.0-py3.6.egg\\flatland\\utils\\graphics_pil.py\u001b[0m in \u001b[0;36malpha_composite_layers\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 209\u001b[0m \u001b[0mimg\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlayers\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 210\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mimg2\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlayers\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 211\u001b[1;33m \u001b[0mimg\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mImage\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0malpha_composite\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mimg\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mimg2\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 212\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mimg\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 213\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mc:\\users\\u216993\\appdata\\local\\programs\\python\\python36\\lib\\site-packages\\PIL\\Image.py\u001b[0m in \u001b[0;36malpha_composite\u001b[1;34m(im1, im2)\u001b[0m\n\u001b[0;32m 2703\u001b[0m \u001b[0mim1\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mload\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2704\u001b[0m \u001b[0mim2\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mload\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 2705\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mim1\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_new\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcore\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0malpha_composite\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mim1\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mim\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mim2\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mim\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 2706\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2707\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mValueError\u001b[0m: images do not match" + ] + } + ], "source": [ "oRT = rt.RenderTool(env,gl=\"PILSVG\")\n", "oRT.render_env()\n", @@ -138,18 +167,6 @@ "language": "python", "name": "python3" }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.8" - }, "latex_envs": { "LaTeX_envs_menu_present": true, "autoclose": false, -- GitLab