{ "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": 15, "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": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Dostupná RAM: 4.4 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": 17, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "00bd0950d47a4fa18002ebc93b358ca3", "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": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "========================================\n", "SOUHRN — Hradec Králové\n", "========================================\n", "Zpracované dlaždice: 5106\n", "Dlaždice s vozidly: 2011\n", "\n", "Detekovaná vozidla:\n", " car : 13886\n", " van : 1\n", " truck : 98\n", " bus : 8\n", " CELKEM : 13993\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": 21, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAHqCAYAAACZcdjsAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAWkNJREFUeJzt3QncTOX///GPfd9ly5JS9gglkiXCVylFJZQiWiiihUjZUiRpIypUFBWSJKJU9izZfVWKEioha5b5P97X93fmPzP33Lf7du7bvb2ej8fc98w515w5c+bMmfM513V9rgyBQCBgAAAAAOBDRj9PBgAAAAACCwAAAACJghoLAAAAAL4RWAAAAADwjcACAAAAgG8EFgAAAAB8I7AAAAAA4BuBBQAAAADfCCwAAAAA+EZgAaRQXbt2tYYNG9qpU6fc4549e9oVV1wRfAxEc9ttt1m2bNls+fLlbCAglfjhhx8sX7581qRJEztx4oSlVA899JBlyZLF5syZk9yrghSKwAJIoZ5//nnbvn27PfXUU/bxxx/b2LFjbcKECZYpUyZLSe666y7LkCGD/fzzz5ZSKCDTOqU306dPt2nTptmLL75otWvXPuvlTJw40W0//U8rLrjgAnc719tAy9D+iKT/zFKrY8eO2S233GJly5Z132GduKfEbTF16lR75ZVXbNy4cdaiRYtkXRekXAQWwFnQSbROGEJvWbNmtVKlSlm7du1s3bp1vrdr3rx57Y033rBhw4bZHXfcYQMGDLDKlSunuSAgrZ7Inmt//fWX3X///W5f0X/gTN+3Z599NtYyTz/9tCvz/vvvp/sNGde2OHjwYPBCRvv27e3kyZNnVQuwb98+Vwug435KtGXLFrvnnnts0KBBdvfddyf36iAFy5zcKwCkZhdddJF16NDB3T906JAtW7bM3nvvPXfVacGCBXbVVVf5Wv61117rgovdu3fbo48+mkhrjbSoe/fuVqxYMVezhZj0fQQS0x9//GHNmze31atX24MPPmijR49OcE2plnH++efb559/biVKlEixH9D3339vI0aMsPvuuy+5VwUpHIEF4EO5cuXc1axQ/fv3t6FDh1q/fv3sq6++8r19uTqE+FBAi7gvAgCJZefOne7Cz9atW11z1cjfgfg677zz3PNTQ98tID5oCgUkMl25kpUrVwanqXr8hRdesGrVqlmO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+fO77eKpV6+eW/auXbvClqNjlspr+4V+BrqQovcbebz45ptv3HKuv/76OLcB0icCC8BHYKErc94Psa6CeVfvs2fPHliyZIkre80117hpy5cvj7GcoUOHunmDBg0KTtNJmKYtXLgwznXQSZOu5GodQn9UPLNmzYpxBe9sAgv9wOk5l156aYx5+lHWj1fkMm+44QY3LfLH0fsx15UzXQWPT2ChK9v6EdN2jEY1EXquAjKPd1KkH2pdkfdOHiN/4L0T/GiBgq6ya57KeHTyo2ktW7YMK7tp0yY3XVf14kNXLVX+6aefjhpYRDs50zzVYIUaPXq0K//GG29Evfq4cePG4LTnnnvOTVPgeybe53HnnXfGOk/bPT5UE6CAQEFgKF1pVc2APl9PQr8rkT766CO3b+nqbWSwFe3ETFeIdUL1+++/x1iWTroj90nVmGja22+/HfX19boKgFJLYBGfW7TAQtss9HOLD302eu7EiRNjBJKqRYikk9fIwCKhxzwFNDox1lX3yJqkhPACC+82duzYMz4nIdtJx1EF/toP33rrrRjbKbb998ILL3TfoWhBio53kfvq66+/7qaNHDkyrOxrr73mpqvW1TN9+vQ4v2+q8VQNtoJDIBSdtwEffvzxRxs4cKC7r/b1ah+sdLN9+vRxbellzZo1ru22BreLpLbjsnbt2uA0tZlXW9YGDRrE+drqNKj2wWqH761DZLYRrz2wH2qTL/Xq1YsxT+2Cq1evHqOTurJjqe3zW2+9FXWZaksd3/VSXxX1yTh+/HjUtszbtm1z/7U89QEJ1bp1a9d+W+2GhwwZEuO5+mwkWj+TaJ/NJZdc4j7HuXPn2p9//mmFCxd209999133X31gItt2K++70lRq/dR34n/nHP+za9euGK+rviPqAxNJfSKWLl0aNk1tt7WvjR8/3jp37uym7dmzx2bPnu36Ragducfri6F+O/FVs2bNqOsh+/fvj9cytE203urroX4j3mem9WnZsmVwG57NdyXUd999515L3wf1x9D+FxelCVX7cW0jtX+PpDb7kZmktF+LBh/Udz/aeATaL0L3jfjS9tT4I35pX45vvymlstb+E42+a9GOK6L9M7b3p75Q6kc1c+ZMt43UByBU6D7vHVu0rSPVqVPHMmfO7OuYp/9aHw06p35efmk5X3zxhT3xxBNuH73sssviLB/XdtK6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2JxJWaLU1Ek0FobHq6WIvK80bAAAAOkdgQVSHG/gvLgGZgltoqRO2J7QsSxCM0d502Mre+zYMVebETnvqquuCk5TjUi0+xqNEgAAIL1L1sBCoyS3bNnSSpQo4U4avavK0dx3332ujDriRo7m3L59ezdgh65wKyVo5EBpagd/9dVXW/bs2d1JoMZHiKS29RUqVHBlqlatanPmzEnEdwpRLYDSv+q2Zs2a4Eb55ZdfgtN1X82UNAq2RrpWytjPP//cBg0a5B57atSoEbxfuXLl4P3evXu7TE5vv/122HgUWl5kWTWz0jgWGpNCTam8wEL743nnnefuq1mU1xxKfSvUYVudv9WB3BNtpG4AAIB0J5CM5syZE+jXr19g+vTpAa3KjBkzopbT/GrVqgVKlCgRGDVqVNi85s2bu3nLli0LfPPNN4Fy5coFbr/99uD8AwcOBIoWLRpo3759YMOGDYH33nsvkCNHjsDrr78eLLN48eJApkyZAsOHDw9s2rQp0L9//0CWLFkC69evj/d70evoPeg/otu+fbvbRnHdJkyY4G5xlalQoUJg3759weV+9913gZw5c8ZavnLlyoEjR44Ey996661xLn/SpElh6/3qq6/GWrZt27aB06dP85EDAIA0KSHnuMkaWISKLbD49ddfA+eff74LCsqUKRMWWCgI0PNWrlwZnPbZZ58FMmTIEPjtt9/c49deey1QoECBwPHjx4NlHn/88UD58uXDTjSvu+66sNetXbt24N577433+hNYJF5gsXnz5kDXrl0DVapUcZ+dgr78+fO7z+SZZ54JHDx4MMayFQQqeCxVqpQLCrNnz+4CkMceeyzw999/h5U9ceJE4MUXXwxcccUVgTx58rjlFypUyAWp2n+imT17dqBBgwaB3Llzu2UrmB09enTg1KlT8d5HAAAAUpuEnOOm6HEslFZUTVHUITe0CYtH4weo+VOtWrXCRmjOmDGjLV++3G666SZXpn79+pY1a9ZgmWbNmrlmNRrcTKlHVUadd0OpTFxNs44fP+5uHjrwntkFF1ygQDYeJc1ef/11S4gqVaq4QfHiI3PmzNajRw93i6/rrrvO3QAAAJAKO2/r5F8ngQ899FDU+bt373ajKodSeWUF0jyvTOT4Bt7jM5Xx5kczbNgwy5cvX/BGB14AAACkZyk2sFi1apWNHj3ajVEQmg0opejb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NQQAAACQ9gIL9bG4/vrr7e2337YWLVpYlixZkmbNAAAAAKTdwEKdttW/AgAAAADOuo8FQQUAAACAROu8DQAAAAAeAgsAAAAAvhFYAAAAADj3gUWnTp3sn3/+iTH98OHDbh4AAACA9CfBgcWkSZPs6NGjMaZrmlLQAgAAAEh/4p1u9uDBgxYIBNxNNRbZs2cPzjt16pTNmTPHihQpklTrCQAAACAtBBb58+e3DBkyuNsll1wSY76mDxw4MLHXDwAAAEBaCiy+/PJLV1txzTXX2EcffWQFCxYMzsuaNauVKVPGSpQokVTrCQAAACAtBBYNGjRw/7dv326lS5d2NRQAAAAAcFadt1Uz8e2331qHDh2sbt269ttvv7np77zzjpsOAAAAIP1JcGChZlDNmjWzHDly2OrVq+348eNu+oEDB+yZZ55JinUEAAAAkNYCiyFDhtjYsWNt/PjxliVLluD0q666ygUaAAAAANKfBAcWW7dutfr168eYni9fPtu/f39irRcAAACAtBxYFCtWzH744YcY09W/4sILL0ys9QIAAACQlgOLLl26WI8ePWz58uUuM9SuXbts8uTJ9sgjj9j999+fNGsJAAAAIG2km/X06dPHTp8+bY0bN7YjR464ZlHZsmVzgcWDDz6YNGsJAAAAIG0FFqql6Nevnz366KOuSdShQ4esUqVKljt37qRZQwAAAABpL7BQWtlTp065kbcVUHj27dtnmTNntrx58yb2OgIAAABI7X0sJk2aZIsWLQo+btu2rb3//vsxyk2bNs3NAwAAAJD+nDGwaNKkiQ0YMMAeeugh91idths1ahSjXMOGDd08AAAAAOnPGQOL888/3/WneOedd9xjjbR98uTJGOVOnDhhR48eTZq1BAAAAJC6Awulkn3ppZdszZo17vEVV1xh48aNi1FOo3HXrFkzadYSAAAAQOruvH311Vdb+/btg4+HDBnimkd9//33LuWsLFiwwFauXGnz5s1L2rUFAAAAkDprLEqXLh32+KqrrrKlS5dayZIlXYftTz75xMqVK2fr1q1zQQgAAACA9CfB6WalevXqNmXKlMRfGwAAAADpJ7DQOBYzZ860zZs3u8eVK1e2G264wTJlypTY6wcAAAAgLTSFiqTRtjUw3p133mnTp093tw4dOrjg4scff0z0Ffztt9/c8gsVKmQ5cuSwqlWr2nff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+EZgAQAAAMA3AgsAAAAAvhFYAAAAAPCNwAIAAACAbwQWAAAAAHwjsAAAAADgG4EFAAAAAN8ILAAAAAD4RmABAAAAwDcCCwAAAAC+EVgAAAAA8I3AAgAAAIBvBBYAAAAAfCOwAAAAAOAbgQUAAAAA3wgsAAAAAPhGYAEAAADANwILAAAAAL4RWAAAAADwjcACAAAAgG8EFgAAAAB8I7AAAAAA4BuBBQAAAADfCCwAAAAA+EZgAQAAAMA3AgsAAAAAvhFYAACQhv3www925513WokSJSxr1qx2/vnn2z333GO//fZbWLlTp07Zyy+/bLVr17a8efNa5syZrXDhwtakSRP76KOPkm39AaQemZN7BQAAQNL4/vvvrX79+nbw4MHgtF27dtmbb75pn332mS1evNguuOACN/3ee+9100P99ddftmDBAnd77bXX7P777+ejAhAraiwAAEijHnzwwWBQ0alTJ5s7d64LILwAo3v37u7+/v37bcKECcHnDRkyxObPn29t27YNTlNgASS1ZcuW2c033+xq2LJkyWI5c+a0qlWr2pNPPmn//PMPH0AKlyEQCASSeyXSAh248+XLZwcOHHBVyOfa6tWrrWbNmmYzzazKOX95pEQbzKyV2apVq6xGjRrJvTbp0r59+2zEiBG2ZMkSW7lypR09etRN79ixo02cODG5Vw9p3KFDh9zvkX7m1QRKJ2X6f/LkSStQoICbnyFDBvvll19c+dKlS7v/av70xx9/uPsbN260KlX+96NSoUIF27x5czK+I6R1X375pTVt2tTto9FceeWV7niq/RYp8xyXGgsASCI7duywZ5991r7++utgUAGcy5MB79qhrvwqqBD1nciWLZu7r/lLly61kiVLWrly5dy0P//804YOHWpffPGFDR48OLi8Dh068OEhSamPjxdUXHPNNa6GTTVl2n+92gxdSEXKRR8LAEgiOpFT+/a6deva3r177a233mJb45wpWrRo8Crj4cOH7fXXX7c77rjDpk2b5vpOeHbu3OmuAM+YMcPatWtn69evt/79+wfnFypUyAUY9K9AUtO+6unVq5c1a9bM3dex87vvvnP3Y6vNQMpAjQUAJJFKlSrZokWLbNiwYXb55ZeznXFOZcqUyXr27Bl8fN9991muXLns7rvvDit37Ngx91/No7TPRlIQ8sEHH9iePXvOwVojPWvY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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 }