{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 04 — Sestavení velké mapy\n", "\n", "Složíme otagované dlaždice (z notebooku 03) do jednoho velkého leteckého snímku HK\n", "se zakreslenými detekcemi vozidel.\n", "\n", "Výsledná mapa: **74 × 69 dlaždic × 256 px = 18 944 × 17 664 px**\n", "(přibližně 90 MB PNG nebo 15 MB JPEG)." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Mřížka: 74 × 69 dlaždic\n", "Výsledná mapa: 18944 × 17664 px\n", "Odhadovaná velikost (JPEG 85%): ~100 MB\n" ] } ], "source": [ "from pathlib import Path\n", "from PIL import Image\n", "import numpy as np\n", "import re\n", "from tqdm.notebook import tqdm\n", "import json\n", "\n", "ANNOTATED_DIR = Path(\"tiles_annotated\")\n", "assert ANNOTATED_DIR.exists(), \"Nejprve spusť 03_inference_tiles.ipynb!\"\n", "\n", "TILE_SIZE = 256\n", "\n", "# Zjistíme rozsah mřížky\n", "tile_files = sorted(ANNOTATED_DIR.glob(\"18_*.jpg\"))\n", "xs = []; ys = []\n", "for f in tile_files:\n", " m = re.match(r\"18_(\\d+)_(\\d+)\\.jpg\", f.name)\n", " if m:\n", " xs.append(int(m.group(1)))\n", " ys.append(int(m.group(2)))\n", "\n", "x_min, x_max = min(xs), max(xs)\n", "y_min, y_max = min(ys), max(ys)\n", "cols = x_max - x_min + 1\n", "rows = y_max - y_min + 1\n", "\n", "W = cols * TILE_SIZE\n", "H = rows * TILE_SIZE\n", "\n", "print(f\"Mřížka: {cols} × {rows} dlaždic\")\n", "print(f\"Výsledná mapa: {W} × {H} px\")\n", "print(f\"Odhadovaná velikost (JPEG 85%): ~{W*H*3/1e6/10:.0f} MB\")" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Dostupná RAM: 10.1 GB, potřeba pro plnou mapu: 1.0 GB\n", "RAM dostačuje — generuji plnou mapu\n" ] } ], "source": [ "# Sestavení mapy — plná rozlišení\n", "# Poznámka: ~18k × 17k px = ~3 GB v RAM → použijeme chunky nebo zmenšenou verzi\n", "\n", "OUTPUT_FULL = Path(\"hk_annotated_full.jpg\")\n", "OUTPUT_PREVIEW = Path(\"hk_annotated_preview.jpg\")\n", "PREVIEW_SCALE = 4 # 1/4 rozlišení pro preview\n", "\n", "# Zkontroluj dostupnou RAM\n", "import psutil\n", "ram_gb = psutil.virtual_memory().available / 1e9\n", "needed_gb = W * H * 3 / 1e9\n", "print(f\"Dostupná RAM: {ram_gb:.1f} GB, potřeba pro plnou mapu: {needed_gb:.1f} GB\")\n", "\n", "if needed_gb > ram_gb * 0.8:\n", " print(\"⚠ Nedostatek RAM pro plnou mapu — generuji pouze preview\")\n", " BUILD_FULL = False\n", "else:\n", " print(\"RAM dostačuje — generuji plnou mapu\")\n", " BUILD_FULL = True" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "ebc786decf254a0485a34ee7d478ca15", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Preview: 0%| | 0/5106 [00:00" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Zobrazení preview mapy v notebooku\n", "import matplotlib.pyplot as plt\n", "import matplotlib.patches as mpatches\n", "\n", "preview = Image.open(OUTPUT_PREVIEW)\n", "\n", "fig, ax = plt.subplots(figsize=(16, 14))\n", "ax.imshow(preview)\n", "ax.set_title(f\"Hradec Králové — detekovaná vozidla\\n(preview {pw}×{ph} px)\", fontsize=14)\n", "ax.axis(\"off\")\n", "\n", "# Legenda\n", "legend_elements = [\n", " mpatches.Patch(facecolor='#00DC00', edgecolor='white', label='car'),\n", " mpatches.Patch(facecolor='#FFDC00', edgecolor='white', label='van'),\n", " mpatches.Patch(facecolor='#DC0000', edgecolor='white', label='truck'),\n", " mpatches.Patch(facecolor='#0078FF', edgecolor='white', label='bus'),\n", "]\n", "ax.legend(handles=legend_elements, loc='lower right', fontsize=12,\n", " framealpha=0.8, title='Typy vozidel')\n", "\n", "plt.tight_layout()\n", "plt.savefig(\"hk_map_overview.png\", dpi=100, bbox_inches=\"tight\")\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "========================================\n", "SOUHRN — Hradec Králové\n", "========================================\n", "Zpracované dlaždice: 5106\n", "Dlaždice s vozidly: 1798\n", "\n", "Detekovaná vozidla:\n", " car : 14812\n", " van : 1454\n", " truck : 375\n", " bus : 488\n", " CELKEM : 17129\n", "========================================\n" ] } ], "source": [ "# Souhrn výsledků\n", "with open(\"detections.json\") as f:\n", " all_detections = json.load(f)\n", "\n", "from collections import Counter\n", "CLASS_NAMES = [\"car\", \"van\", \"truck\", \"bus\"]\n", "counts = Counter()\n", "tiles_with_vehicles = 0\n", "\n", "for name, dets in all_detections.items():\n", " if dets:\n", " tiles_with_vehicles += 1\n", " for d in dets:\n", " counts[CLASS_NAMES[d[\"cls\"]]] += 1\n", "\n", "print(\"=\" * 40)\n", "print(\"SOUHRN — Hradec Králové\")\n", "print(\"=\" * 40)\n", "print(f\"Zpracované dlaždice: {len(all_detections):6d}\")\n", "print(f\"Dlaždice s vozidly: {tiles_with_vehicles:6d}\")\n", "print()\n", "print(\"Detekovaná vozidla:\")\n", "for cls in CLASS_NAMES:\n", " print(f\" {cls:10s}: {counts[cls]:6d}\")\n", "print(f\" {'CELKEM':10s}: {sum(counts.values()):6d}\")\n", "print(\"=\" * 40)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "image/png": "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3n33XbcdW7ZscdV7snDhQrvpppvC1rt161abPHmyff311/brr7/anj17LEeOHFalShXr2rWr3XnnnT6OGAAAgNQjPk39CSxwUezYscNefvnlBD3n1KlT9uCDDwaDikg2b95s1atXtyNHjgTnnT592n766Sc3zZo1y9avX285c+Z0y6ZPn25vv/12vF7/k08+sQEDBsTYpgULFrhpxIgR1r179wS9JwAAgLSKrFC4KLJkyWJ169a1p59+2jp06BCv5wwePNg2bNhg2bJli7XM+PHjg0FFpUqVbObMmfbee+9Z3rx53TzVNMyZMydYXrUXzZs3t2HDhtk111xz3m3IkyePdevWza33008/tRo1agSXPfvss3b06NF4vRcAAIC0jhoLXBTlypVzzZBk3Lhx56012Lhxo7300kuWPXt269mzp73wwgsRyx08eDD4d6dOnYIjD3/22Wf28ccfu7/PnDkTLNOnT5/g3x9++GGc29CgQQPr3Lmz5c+fPzhPwVGRIkXcOo8dO+YCH9WYAAAApHcEFkhx1PRJTaDU7Ej9MgoWLBhrWfWL8IKUCRMm2OWXX2779++3r776ys0rVKiQNWzY8IK2o1q1ajHmFShQwPLly2d//fWXe+w1sQIAAEjvaAqFFGfMmDG2bNkyq1q1qj3xxBNxlm3btq2rhciaNat9//33rsbivvvuswMHDri/1UlbgUBi+eabb4JBhYKYsmXLJtq6AQAAUjMCC6S4Tt7K5JQpUyZ76623XIan82UouPrqq8MyP3mWLFniOlknlm3btlmbNm2Crzt69OjzDhQDAACQXnBVhBRFnbvVGbtXr16uM/b5KFWtOoMrIFGn7L///tt+/vlnV5OgWgv1kVCthV9KaVunTh03TomMGjXKmjZt6nu9AAAAaQWBBVLcCOZeRijVCmh64IEHgsunTZvm5s2YMSPYr8KjYEQdra+88kq7//77g/O9shdq7dq1Vq9ePfvjjz/ca6up1uOPP+5rnQAAAGkNnbeRqv33v/8N/h06lsXhw4cjzk8o1XY0adLEZZ9S86yJEye6fh0AAAAIR2CBi0KpWWfPnh2sAfBs3749mBb2+uuvty5dulizZs3Cnrty5Ur74IMP3N/XXXedtWvXzipWrOgely9f3g2EJ0pLO3DgQJcV6o033gg+v3LlymFpbDV5o4F7lArXC1LUpMrr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t1UzsWTJEmvbtq3VqlXL/vjjDzf/vffec/MBAAAApD8JDizUDKpRo0aWPXt2W7NmjZ08edLNP3jwoL300ktJsY0AAAAA0lpg8cILL9i4ceNswoQJljlz5uD8G2+80QUaAAAAANKfBAcWW7Zssbp168aYnydPHjtw4EBibRcAAACAtBxYFClSxH7++ecY89W/4oorrkis7QIAAACQlgOLTp06Wbdu3WzFihUuM9SuXbts8uTJ9uSTT9ojjzySNFsJAAAAIG2km/U8/fTTdu7cOatfv74dO3bMNYvKmjWrCywef/zxpNlKAAAAAGkrsFAtxbPPPmu9evVyTaKOHDli5cqVs1y5ciXNFgIAAABIe4GF0sqePXvWjbytgMKzb98+y5Qpk+XOnTuxtxEAAABAau9j8c4779iiRYuCj1u2bGlTp06NUe7DDz90ywAAAACkP+cNLBo0aGD9+vWzrl27usfqtH3zzTfHKHfTTTe5ZQAAAADSn/MGFpdddpnrT/Hee++5xxpp+8yZMzHKnT592o4fP540WwkAAAAgdQcWSiU7evRoW7t2rXtcvXp1Gz9+fIxyGo27atWqSbOVAAAAAFJ35+06depYmzZtgo9feOEF1zzq+++/dylnZf78+bZq1SqbO3du0m4tAAAAgNRZY1GiRImwxzfeeKMtW7bMihUr5jpsz5w506666ipbv369C0IAAAAApD8JTjcrlStXtilTpiT+1gAAAABIP4GFxrGYMWOGbdq0yT0uX7683XHHHZYxY8bE3j4AAAAAaTGw0Gjbt912m/3+++9WunRpN2/w4MFWvHhx++KLL+zKK69Miu0EAAAAkJr7WESn8SyuuOIK27lzp61Zs8ZNO3bssFKlSgXHugAAAACQviS4xkKjcC9fvtzy588fnFegQAF7+eWXXcduAAAAAOlPgmsssmbNaocPH44x/8iRI5YlS5bE2i4AAAAAaTmwuP32261z5862YsUKCwQCblINxsMPP+w6cAMAAABIfxIcWGgUbnXQrlmzpmXLls1NagKlsSxGjRqVNFsJAAAAIG31scibN6999tlnLjuUl262bNmyLrAAAAAAkD7FO7A4d+6cDR061D7//HM7deqU1a9f355//nnLnj170m4hAAAAgLTTFOrFF1+0Z555xnLlymWXXXaZa/b02GOPJe3WAQAAAEhbgcW7775r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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Sloupcový graf celkových počtů\n", "fig, ax = plt.subplots(figsize=(8, 5))\n", "\n", "bar_colors = [\"#00DC00\", \"#FFDC00\", \"#DC0000\", \"#0078FF\"]\n", "bars = ax.bar(CLASS_NAMES, [counts[c] for c in CLASS_NAMES], color=bar_colors, edgecolor=\"black\")\n", "\n", "for bar, cls in zip(bars, CLASS_NAMES):\n", " ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 5,\n", " str(counts[cls]), ha=\"center\", va=\"bottom\", fontsize=12, fontweight=\"bold\")\n", "\n", "ax.set_title(\"Počet detekovaných vozidel — Hradec Králové\", fontsize=14)\n", "ax.set_ylabel(\"Počet vozidel\")\n", "ax.set_xlabel(\"Typ vozidla\")\n", "plt.tight_layout()\n", "plt.savefig(\"vehicle_counts_chart.png\", dpi=150, bbox_inches=\"tight\")\n", "plt.show()" ] } ], "metadata": { "kernelspec": { "display_name": ".venv (3.14.4)", "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.14.4" } }, "nbformat": 4, "nbformat_minor": 4 }