2024-11-29 02:35:02 +01:00
{
"cells": [
{
"cell_type": "code",
2024-11-29 07:15:25 +01:00
"execution_count": 24,
2024-11-29 02:35:02 +01:00
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1500x1000 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1500x1000 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABJ4AAAJvCAYAAAA6DRtsAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOz9ebBsWVnmj3/WsIfMM9x7q6iBKhCwkElbaQdAERFQSkAmIVRUBJwIVAQCMFAUCqQFVAQDbDQwBBqxUWgFlFEUWnFoNKRthy8/pmKQrunWHc7Jk7n3XtPvj3etnXluFVBgFVWX3o9xpG6ePJl7XHu9z3qe51UppcSECRMmTJgwYcKECRMmTJgwYcKECTcy9M29ARMmTJgwYcKECRMmTJgwYcKECRO+PDERTxMmTJgwYcKECRMmTJgwYcKECRNuEkzE04QJEyZMmDBhwoQJEyZMmDBhwoSbBBPxNGHChAkTJkyYMGHChAkTJkyYMOEmwUQ8TZgwYcKECRMmTJgwYcKECRMmTLhJMBFPEyZMmDBhwoQJEyZMmDBhwoQJE24STMTThAkTJkyYMGHChAkTJkyYMGHChJsEE/E0YcKECRMmTJgwYcKECRMmTJgw4SbBRDxNmDBhwoQJEyZMmDBhwoQJEyZMuEkwEU8TJkyYMGHChLMCt7/97Xn84x9/c2/GLRpKKS677LKbezNuNHziE59AKcVrXvOam3tTJkyYMGHChAlfJCbiacKECRMmTPgS4TWveQ1KqfGnbVvudKc78dM//dNcddVVN/fmfdlAKcVP//RP39yb8f8s/vmf/xmlFB/4wAcAeNrTnsbXf/3Xc8455zCfz7nrXe/KZZddxmKxuJm3dMKECRMmTJjwpYC9uTdgwoQJEyZM+H8Nz3/+87nDHe5A13W8//3v55WvfCVvf/vb+Zd/+Rfm8/nNvXkTzmKsViusvXmnd29729s4//zz+aZv+iYA/v7v/5773Oc+POEJT6BtWz74wQ/yohe9iPe85z385V/+JVp/9nXQ293udqxWK6qq+lJt/oQJEyZMmDDhRsZEPE2YMGHChAlfYjzoQQ/iG7/xGwH4sR/7Mc4991x+/dd/nbe85S085jGPud6/OTg4YGtr60u5mRPOQrRte3NvAm9/+9t50IMehFIKgPe///3Xec8ll1zCM57xDD7wgQ9wr3vd67N+VlEGTpgwYcKECRPOXkxWuwkTJkyYMOFmxv3vf38ALr/8cgAe//jHs729zcc+9jEe/OAHs7Ozww/+4A8CQkA9/elP57a3vS1N03DnO9+ZX/u1XyOldJ3P/b3f+z3ucY97MJ/POXbsGN/2bd/Gu9/97kPvecc73sF97nMftra22NnZ4SEPeQj/+q//eug9V155JU94whO4zW1uQ9M03PrWt+bhD384n/jEJ8b3/MM//AOXXnopt7rVrZjNZtzhDnfgR37kRw59ToyRl73sZXz1V381bdtywQUX8MQnPpGTJ08eel9KiRe84AXc5ja3YT6fc7/73e862/SF4H3vex9KKf7wD/+Q5z3veVx88cXs7Ozw6Ec/mtOnT9P3PU996lM5//zz2d7e5glPeAJ93x/6jFe/+tXc//735/zzz6dpGu52t7vxyle+8jrfFWPksssu46KLLhq3/d/+7d+uN5/q1KlTPPWpTx3P5R3veEde/OIXE2M89L4rrriCD33oQzjnPu++npnxdNlll6GU4sMf/jA/9EM/xJEjRzjvvPP4xV/8RVJKfPrTn+bhD384u7u7XHjhhbzkJS+5zmd+8pOf5GEPexhbW1ucf/75PO1pT+Nd73oXSine9773XWef/uZv/oaHPOQhn3M7b3/724/v/1y4voyncn98/OMf59JLL2Vra4uLLrqI5z//+de5D6699loe+9jHsru7y9GjR3nc4x7HP/3TP025URMmTJgwYcKXEJPiacKECRMmTLiZ8bGPfQyAc889d3zNe8+ll17Kt37rt/Jrv/ZrzOdzUko87GEP473vfS8/+qM/yt3vfnfe9a538cxnPpPPfOYzvPSlLx3//nnPex6XXXYZ3/It38Lzn/986rrmf/2v/8Vf/MVf8MAHPhCA173udTzucY/j0ksv5cUvfjHL5ZJXvvKVfOu3fisf/OAHR3LgUY96FP/6r//Kk5/8ZG5/+9tz9dVX82d/9md86lOfGv/9wAc+kPPOO49nPetZHD16lE984hP80R/90aH9fOITn8hrXvManvCEJ/AzP/MzXH755bziFa/ggx/8IH/913892qme85zn8IIXvIAHP/jBPPjBD+Yf//EfeeADH8gwDP+h4/zCF76Q2WzGs571LD760Y/y8pe/nKqq0Fpz8uRJLrvsMv7u7/6O17zmNdzhDnfgOc95zvi3r3zlK/nqr/5qHvawh2Gt5U/+5E/4yZ/8SWKM/NRP/dT4vp/7uZ/jV37lV3joQx/KpZdeyj/90z9x6aWX0nXdoW1ZLpfc97735TOf+QxPfOIT+Yqv+Ar+5m/+hp/7uZ/jiiuu4GUve9mhz3zta1/L5ZdfPp6TLxTf933fx13velde9KIX8ba3vY0XvOAFnHPOOfz2b/8297///Xnxi1/M61//ep7xjGfwTd/0TXzbt30bIETn/e9/f6644gqe8pSncOGFF/L7v//7vPe9773e7ymEVLnGCrz3nDp1imEY+Jd/+Rd+4Rd+gZ2dHe5xj3t8UfsTQuC7vuu7uNe97sWv/Mqv8M53vpPnPve5eO95/vOfDwgJ+NCHPpQPfOADPOlJT+Iud7kLb3nLW3jc4x73RX3nhAkTJkyYMOGLRJowYcKECRMmfEnw6le/OgHpPe95T7rmmmvSpz/96fSGN7whnXvuuWk2m6V///d/Tyml9LjHPS4B6VnPetahv3/zm9+cgPSCF7zg0OuPfvSjk1IqffSjH00ppfSRj3wkaa3TIx/5yBRCOPTeGGNKKaX9/f109OjR9OM//uOHfn/llVemI0eOjK+fPHkyAelXf/VXP+t+/fEf/3EC0t///d9/1vf81V/9VQLS61//+kOvv/Od7zz0+tVXX53quk4PechDxm1NKaWf//mfT0B63OMe91m/owBIP/VTPzX++73vfW8C0td8zdekYRjG1x/zmMckpVR60IMedOjvv/mbvznd7na3O/Tacrm8zvdceuml6Su/8ivHf1955ZXJWpse8YhHHHrfZZdddp1t/6Vf+qW0tbWVPvzhDx9677Oe9axkjEmf+tSnxtfK9XD55ZffoH1/7nOfO/77uc99bgLST/zET4yvee/TbW5zm6SUSi960YvG10+ePJlms9mh7XzJS16SgPTmN795fG21WqW73OUuCUjvfe97D33/Yx/72HTf+973Otv1t3/7twkYf+585ztf52+vD5dffnkC0qtf/erxtXI8nvzkJ4+vxRjTQx7ykFTXdbrmmmtSSin9j//xPxKQXvayl43vCyGk+9///tf5zAkTJkyYMGHCTYfJajdhwoQJEyZ8ifEd3/EdnHfeedz2trfl+7//+9ne3uaP//iPufjiiw+970lPetKhf7/97W/HGMPP/MzPHHr96U9/Oikl3vGOdwDw5je/mRgjz3nOc64T3Fxyd/7sz/6MU6dO8ZjHPIbjx4+PP8YY7nnPe46KltlsRl3XvO9977uOJa7g6NGjAPzpn/7pZ7WDvfGNb+TIkSN853d+56Hv+4Zv+Aa2t7fH73vPe97DMAw8+clPHrcV4KlPfepnO5w3GD/8wz98KKT6nve8Jyml61gC73nPe/LpT38a7/342mw2G//79OnTHD9+nPve9758/OMf5/Tp0wD8+Z//Od57fvInf/LQ5z35yU++zra88Y1v5D73uQ/Hjh07dDy+4zu+gxACf/mXfzm+9zWveQ0ppS9a7QSSJVZgjOEbv/EbSSnxoz/6o+PrR48e5c53vjMf//jHx9fe+c53cvHFF/Owhz1sfK1tW378x3/8Ot8RY+Sd73zn9drs7na3u/Fnf/ZnvPnNb+Znf/Zn2dra+g93tdvsXFg6GQ7DwHve855x26uqOrStWutDCrUJEyZMmDBhwk2PyWo
"text/plain": [
"<Figure size 1500x1000 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import numpy as np\n",
"import cv2\n",
"from matplotlib import pyplot as plt\n",
"\n",
"def order_points(pts):\n",
" rect = np.zeros((4, 2), dtype=\"float32\")\n",
" s = pts.sum(axis=1)\n",
" rect[0] = pts[np.argmin(s)]\n",
" rect[2] = pts[np.argmax(s)]\n",
" diff = np.diff(pts, axis=1)\n",
" rect[1] = pts[np.argmin(diff)]\n",
" rect[3] = pts[np.argmax(diff)]\n",
" return rect\n",
"\n",
"def get_transform(image, pts, padding=0.1):\n",
" rect = order_points(pts)\n",
" (tl, tr, br, bl) = rect\n",
" widthA = np.linalg.norm(br - bl)\n",
" widthB = np.linalg.norm(tr - tl)\n",
" maxWidth = max(int(widthA), int(widthB))\n",
" heightA = np.linalg.norm(tr - br)\n",
" heightB = np.linalg.norm(tl - bl)\n",
" maxHeight = max(int(heightA), int(heightB))\n",
" center = np.mean(rect, axis=0)\n",
" vectors = rect - center\n",
" rect_shrinked = rect - vectors * padding\n",
" rect_shrinked[:, 0] = np.clip(rect_shrinked[:, 0], 0, image.shape[1] - 1)\n",
" rect_shrinked[:, 1] = np.clip(rect_shrinked[:, 1], 0, image.shape[0] - 1)\n",
" dst = np.array([\n",
" [0, 0],\n",
" [maxWidth - 1, 0],\n",
" [maxWidth - 1, maxHeight - 1],\n",
" [0, maxHeight - 1]\n",
" ], dtype=\"float32\")\n",
" M = cv2.getPerspectiveTransform(rect_shrinked, dst)\n",
" warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))\n",
" return warped\n",
"\n",
"def get_transformed_plate(image, bbox, padding=0.1):\n",
" plate = get_transform(image, bbox, padding)\n",
" return plate\n",
"\n",
"def process_and_display_plate(image_path, padding=0.1):\n",
" image = cv2.imread(image_path)\n",
" if image is None:\n",
" print(f\"Failed to load image at path: {image_path}\")\n",
" return\n",
" output_image = image.copy()\n",
" img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n",
" ret, thresh = cv2.threshold(img_gray, 100, 200, cv2.THRESH_TOZERO_INV)\n",
" contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)\n",
" plate_found = False\n",
" plate_image = None\n",
" plate_box = None\n",
" for cnt in contours:\n",
" x, y, w, h = cv2.boundingRect(cnt)\n",
" area = w * h\n",
" aspectRatio = float(w) / h\n",
" if aspectRatio >= 3 and area > 600:\n",
" approx = cv2.approxPolyDP(cnt, 0.05 * cv2.arcLength(cnt, True), True)\n",
" if len(approx) <= 4 and x > 15:\n",
" rect = cv2.minAreaRect(cnt)\n",
" box = cv2.boxPoints(rect)\n",
" box = np.intp(box)\n",
" plate_image = get_transformed_plate(image, box, padding)\n",
" plate_found = True\n",
" plate_box = box\n",
" break\n",
" if plate_found:\n",
" cv2.polylines(output_image, [plate_box], isClosed=True, color=(0, 255, 0), thickness=2)\n",
" height, width = image.shape[:2]\n",
" black_space_width = width // 2\n",
" black_space = np.zeros((height, black_space_width, 3), dtype=np.uint8)\n",
" if plate_found and plate_image is not None:\n",
" plate_height, plate_width = plate_image.shape[:2]\n",
" scale_factor = min(black_space_width / (plate_width + 200), height / plate_height)\n",
" new_plate_width = int(plate_width * scale_factor)\n",
" new_plate_height = int(plate_height * scale_factor)\n",
" resized_plate = cv2.resize(plate_image, (new_plate_width, new_plate_height), interpolation=cv2.INTER_AREA)\n",
" y_offset = (height - new_plate_height) // 2\n",
" black_space[y_offset:y_offset + new_plate_height, 0:new_plate_width] = resized_plate\n",
" placeholder_text = \"Text plate:\"\n",
" decoded_text = \"__________\"\n",
" font = cv2.FONT_HERSHEY_SIMPLEX\n",
" font_scale = 1\n",
" font_color = (255, 255, 255)\n",
" thickness = 2\n",
" line_type = cv2.LINE_AA\n",
" cv2.putText(black_space, placeholder_text, (new_plate_width + 20, y_offset + new_plate_height // 2), \n",
" font, font_scale, font_color, thickness, line_type)\n",
" cv2.putText(black_space, decoded_text, (new_plate_width + 20, y_offset + new_plate_height // 2 + 50), \n",
" font, font_scale, font_color, thickness, line_type)\n",
" else:\n",
" placeholder_text = \"Not found.\"\n",
" font = cv2.FONT_HERSHEY_SIMPLEX\n",
" font_scale = 1\n",
" font_color = (0, 0, 255)\n",
" thickness = 2\n",
" line_type = cv2.LINE_AA\n",
" text_size, _ = cv2.getTextSize(placeholder_text, font, font_scale, thickness)\n",
" text_x = (black_space_width - text_size[0]) // 2\n",
" text_y = height // 2\n",
" cv2.putText(black_space, placeholder_text, (text_x, text_y), \n",
" font, font_scale, font_color, thickness, line_type)\n",
" combined_image = np.hstack((output_image, black_space))\n",
" combined_image_rgb = cv2.cvtColor(combined_image, cv2.COLOR_BGR2RGB)\n",
" plt.figure(figsize=(15, 10))\n",
" plt.imshow(combined_image_rgb)\n",
" plt.axis('off')\n",
" plt.title(f'Processed Image: {image_path}')\n",
" plt.show()\n",
"\n",
"images = ['img/1.jpg', 'img/2.jpg', 'img/3.jpg']\n",
"\n",
"for img_path in images:\n",
" process_and_display_plate(img_path, padding=0.1)\n"
]
},
{
"cell_type": "code",
2024-11-29 07:15:25 +01:00
"execution_count": 26,
2024-11-29 02:35:02 +01:00
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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fOIT2d/f56d/+qd52MMexh//8R9zn/vch8suu+zY9n75l3+ZV73qVcdeu/Od7/xR90VEeNSjHsUb3/hGvumbvon73Oc+vP71r+e7vuu7uO666/jxH/9xAM6ePctms+FJT3oSD3nIQ/jWb/1W/u7v/o7nP//5/NEf/RF/9Ed/RNu243bPnz/PIx7xCL7qq76KxzzmMfyP//E/eNKTnkTTNKN65pYc3/Dd73rXu/hP/+k/8RVf8RU89alP5U//9E959rOfzdve9jZe85rXjETI933f9/H93//9PPShD+VJT3oS73jHO3jBC17An/zJn/D7v//7hBB4xjOewTd/8zcfu4bf8i3fwgMe8ICPe+2++Zu/mTe96U385m/+Jve85z0/6vsuXLhwE+JywOMe9zje/OY3f8Km6DlnHv7wh/MFX/AF/Nf/+l95+ctfzrd/+7ezXC55xjOewdd93dfxFV/xFbzwhS/kcY97HPe///25053uBMB1113Hgx/8YIwxPP3pT2e5XPKSl7zk2LU7ite+9rVcfvnlowrxtsItGS+Hh4c85CEP4frrr+c7v/M7ud3tbscv/MIv3ISonDBhwoQJEyZUyIQJEyZMmDBhxEtf+lIB5Ld+67fkwx/+sLz//e+XV7ziFXLmzBmZz+fygQ98QERE/vN//s+yXC7lb/7mb459/ru/+7vFOSfve9/7Pup3fNu3fZvs7OyMv7/+9a8XQH7jN37j2Ps+4zM+Qx74wAfe5POf93mfJw9+8IPH39/97ncLIC996UvH1x74wAfKve51r1t93O9+97tv8reUknRdd+y18+fPyxVXXCHf+I3feLPbe+Yznym3Zpnx6le/WgB51rOedez1f/tv/60YY+Sd73znse1+4Rd+oaSUbrL/z33uc8fXHvjABwogP/qjPzq+1nWd3Oc+95HLL79c+r6/Vcf3+Mc/XgB5whOecLPH+mu/9msiInLDDTdI0zTyxV/8xZJzHt/3vOc9TwD5mZ/5mZsc/81dw6MA5JnPfKaIiDz96U8X55y8+tWv/pjvExF52tOeJpdffrnc9773vclYGs7Px8PN7dtwLn7wB39wfO38+fMyn8/FGCOveMUrxtff/va332S/vuM7vkOMMfIXf/EX42tnz56VSy655GbH4QMe8AB5/OMf/1H3cblcfsy/fyTe+MY3CiBvfOMbx9du6Xj50R/9UQGOnf/1ei33uMc9brLNCRMmTJgwYYLIVGo3YcKECRMm3Awe+tCHctlll3GHO9yBr/mar2FnZ4dXvepVo6/Q//yf/5MHPOABnD59mhtvvHH8eehDH0rOmd/93d89tr2LFy/yoQ99iN/+7d/mNa95DV/wBV9w7LuuuuoqXv7yl4+vve1tb+Otb30rX//1X3+Tfev7/qMqQ44i5zzuV9/3n+ipwDk3mjCXUjh37hwpJT77sz+bP//zP/+Et3sUr33ta3HO8e///b8/9vpTn/pURITf+I3fOPb6f/gP/+GYOuyxj30sV1xxBa95zWuOvc97z7XXXjv+3jQN1157LTfccAN/9md/9gkd33d913cd+/0pT3kKzrnxu3/rt36Lvu958pOfjLXbpdYTn/hETpw4cZN9vDV43vOexw/90A/xnOc8hy//8i//mO+97rrreO5zn8v3fM/33KwH0pve9KZPWO0
"text/plain": [
"<Figure size 1500x1000 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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djz3vOc9ef7znw/AkSNHePazn/0Fn9Nv/uZvDv/9p3/6p7z61a/ml3/5l4eAvvhZnTx5kte85jU88YlP5GlPexrb29u89rWv5bLLLuMv//Ivuf/9789555235/N+93d/lze96U17Xrv00ks/67GICI973ON417vexQ/8wA9w//vfn3e84x0897nP5frrr+eXf/mXAbjttttYrVY84xnP4OEPfzhPf/rT+cQnPsErXvEK3ve+9/G+972PpmmGzz127BiPfvSj+Y7v+A6e+MQn8t/+23/jGc94BnVdD+qZszm/8t2f/OQn+fEf/3G+/du/nec85zn81V/9FS95yUv48Ic/zFve8paBLHrRi17ET/3UT/GIRzyCZzzjGXzsYx/j137t13j/+9/Pn/3Zn1FVFc9//vP5wR/8wT338Id+6Id48IMf/Hnv3Q/+4A/y7ne/m//xP/4H9773vT/r+44fP34acVnw5Cc/mT/5kz/5ok3RY4w86lGP4hu+4Rv4T//pP3H11Vfz7/7dv2Nzc5PnP//5fM/3fA/f/u3fzitf+Uqe/OQn88AHPpA73/nOAFx//fU87GEPwxjD8573PDY3N3nNa16z596t461vfSvnn3/+oEL8bLjpppvY2Nj4osthz2a87O7u8vCHP5wbb7yRZz7zmdzudrfjt37rt04jKidMmDBhwoQJGTJhwoQJEyZMGHDVVVcJIH/0R38kt956q3zmM5+RN7zhDXLOOefIfD6X6667TkRE/uN//I+yubkpf//3f7/n93/sx35MnHNy7bXXftbv+OEf/mHZ2toa/v2Od7xDAHnb2962531f+ZVfKQ95yENO+/0HPehB8rCHPWz49zXXXCOAXHXVVcNrD3nIQ+Q+97nPF3ze11xzzWk/CyFI27Z7Xjt27JhccMEF8v3f//1n/LwXvvCF8oVsM9785jcLID/zMz+z5/V/82/+jRhj5B/+4R/2fO43fuM3SgjhtON/+ctfPrz2kIc8RAD5xV/8xeG1tm3l/ve/v5x//vnSdd0XdH5PecpTBJCnPvWpZzzXP/iDPxARkVtuuUXqupZv+qZvkhjj8L4rr7xSAHnd61532vmf6R6uA5AXvvCFIiLyvOc9T5xz8uY3v/lzvk9E5IorrpDzzz9fHvCAB5w2lsr1+Xw407GVa/GzP/uzw2vHjh2T+Xwuxhh5wxveMLz+0Y9+9LTj+pEf+RExxshf//VfD6/ddtttcvjw4TOOwwc/+MHylKc85XMe58c//nGZzWbypCc96fOe07ve9S4B5F3vetfw2tmOl1/8xV8UYM/1Xy6Xcs973vO0z5wwYcKECRMmiEyldhMmTJgwYcIZ8IhHPILzzjuPO9zhDnzXd30XW1tbvOlNbxp8hf77f//vPPjBD+bQoUMcOXJk+POIRzyCGCPvec979nzeiRMnuPnmm/njP/5j3vKWt/AN3/ANe77roosu4uqrrx5e+/CHP8zf/u3f8r3f+72nHVvXdZ9VGbKOGONwXF3XfbGXAuccdV0Dasp89OhRQgh8zdd8DR/84Ae/6M9dx1vf+lacc/zoj/7ontef85znICK87W1v2/P6v//3/36POuxJT3oSF1xwAW95y1v2vM97z+WXXz78u65rLr/8cm655RY+8IEPfFHn99znPnfPv5/97GfjnBu++4/
"text/plain": [
"<Figure size 1500x1000 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1500x1000 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import numpy as np\n",
"import cv2\n",
"from matplotlib import pyplot as plt\n",
"import torch\n",
"import torch.nn as nn\n",
"from torchvision import transforms\n",
"\n",
"# Конфигурация устройства\n",
"DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
"\n",
"# Классы символов для модели OCR\n",
"CLASSES = \"ABEKMHOPCTYX0123456789\"\n",
"\n",
"# Трансформации для входных изображений\n",
"transform = transforms.Compose([\n",
" transforms.ToPILImage(),\n",
" transforms.Grayscale(),\n",
" transforms.Resize((28, 28)),\n",
" transforms.ToTensor(),\n",
" transforms.Normalize((0.25,), (0.25,))\n",
"])\n",
"\n",
"# Определение модели CNN\n",
"class ImprovedCNN(nn.Module):\n",
" def __init__(self, num_classes):\n",
" super(ImprovedCNN, self).__init__()\n",
" self.conv_layers = nn.Sequential(\n",
" nn.Conv2d(1, 32, kernel_size=3, padding=1),\n",
" nn.SiLU(),\n",
" nn.BatchNorm2d(32),\n",
" nn.MaxPool2d(kernel_size=2, stride=2),\n",
"\n",
" nn.Conv2d(32, 64, kernel_size=3, padding=1),\n",
" nn.SiLU(),\n",
" nn.BatchNorm2d(64),\n",
" nn.MaxPool2d(kernel_size=2, stride=2),\n",
"\n",
" nn.Conv2d(64, 128, kernel_size=3, padding=1),\n",
" nn.SiLU(),\n",
" nn.BatchNorm2d(128),\n",
" nn.AdaptiveAvgPool2d((1, 1)) # Глобальный Average Pooling\n",
" )\n",
" self.fc_layers = nn.Sequential(\n",
" nn.Linear(128, 256),\n",
" nn.SiLU(),\n",
" nn.Linear(256, num_classes)\n",
" )\n",
"\n",
" def forward(self, x):\n",
" x = self.conv_layers(x)\n",
" x = x.view(x.size(0), -1) # Разворачиваем перед линейным слоем\n",
" x = self.fc_layers(x)\n",
" return x\n",
"# Загрузка предобученной модели\n",
"model = ImprovedCNN(len(CLASSES)).to(DEVICE)\n",
"SAVE_PATH = \"best_model_9.pth\"\n",
"try:\n",
" model.load_state_dict(torch.load(SAVE_PATH, map_location=DEVICE))\n",
" model.eval()\n",
"except Exception as e:\n",
" print(f\"Ошибка при загрузке модели: {e}\")\n",
"\n",
"# Функции для распознавания номера\n",
"def extract_symbols(image, masks):\n",
" img_h, img_w = image.shape\n",
" symbols = []\n",
" for bbox in masks:\n",
" x_frac, y_frac, w_frac, h_frac = bbox\n",
" x = int(x_frac * img_w)\n",
" y = int(y_frac * img_h)\n",
" w = int(w_frac * img_w)\n",
" h = int(h_frac * img_h)\n",
" x_end = min(x + w, img_w)\n",
" y_end = min(y + h, img_h)\n",
" symbol = image[y:y_end, x:x_end]\n",
" if symbol.size == 0:\n",
" continue\n",
" symbols.append(symbol)\n",
" return symbols\n",
"\n",
"def is_symbol_present(symbol, threshold=250):\n",
" return np.mean(symbol) < threshold\n",
"\n",
"expected_types_8 = ['letter', 'digit', 'digit', 'digit', 'letter', 'letter', 'digit', 'digit']\n",
"expected_types_9 = ['letter', 'digit', 'digit', 'digit', 'letter', 'letter', 'digit', 'digit', 'digit']\n",
"\n",
"mask_8 = [\n",
" (0.03, 0.05, 0.12, 0.9),\n",
" (0.16, 0.05, 0.12, 0.9),\n",
" (0.28, 0.05, 0.12, 0.9),\n",
" (0.40, 0.05, 0.12, 0.9),\n",
" (0.52, 0.05, 0.12, 0.9),\n",
" (0.64, 0.05, 0.12, 0.9),\n",
" (0.79, 0.07, 0.10, 0.60),\n",
" (0.89, 0.07, 0.10, 0.60),\n",
"]\n",
"\n",
"mask_9 = [\n",
" (0.05, 0.2, 0.1, 0.6),\n",
" (0.17, 0.2, 0.1, 0.6),\n",
" (0.29, 0.2, 0.1, 0.6),\n",
" (0.41, 0.2, 0.1, 0.6),\n",
" (0.53, 0.2, 0.1, 0.6),\n",
" (0.65, 0.2, 0.1, 0.6),\n",
" (0.77, 0.2, 0.1, 0.6),\n",
" (0.89, 0.2, 0.1, 0.6),\n",
" (1.01, 0.2, 0.1, 0.6)\n",
"]\n",
"\n",
"digits = set(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'])\n",
"letters = set([c for c in CLASSES if c.isalpha()])\n",
"\n",
"def process_plate(plate):\n",
" gray_plate = cv2.cvtColor(plate, cv2.COLOR_BGR2GRAY)\n",
" resized_plate = cv2.resize(gray_plate, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)\n",
" blurred = cv2.GaussianBlur(resized_plate, (3, 3), 0)\n",
" symbols_8 = extract_symbols(blurred, mask_8)\n",
" symbols_9 = extract_symbols(blurred, mask_9)\n",
" if len(symbols_9) == 9 and is_symbol_present(symbols_9[-1]):\n",
" characters = symbols_9\n",
" expected_types = expected_types_9\n",
" else:\n",
" characters = symbols_8\n",
" expected_types = expected_types_8\n",
" return blurred, characters, expected_types\n",
"\n",
"def recognize_plate(plate_image):\n",
" if plate_image is None:\n",
" return None\n",
" processed_plate, characters, expected_types = process_plate(plate_image)\n",
" predictions = []\n",
" for idx, (symbol_img, expected_type) in enumerate(zip(characters, expected_types)):\n",
" input_tensor = transform(symbol_img).unsqueeze(0).to(DEVICE)\n",
" with torch.no_grad():\n",
" outputs = model(input_tensor)\n",
" probabilities = torch.nn.functional.softmax(outputs, dim=1)\n",
" indices = torch.argmax(probabilities, dim=1)\n",
" predicted_label = CLASSES[indices[0]]\n",
" if expected_type == 'letter':\n",
" if predicted_label == '0':\n",
" predicted_label = 'O'\n",
" elif predicted_label == '8':\n",
" predicted_label = 'B'\n",
" if predicted_label not in letters:\n",
" continue\n",
" elif expected_type == 'digit':\n",
" if predicted_label == 'O':\n",
" predicted_label = '0'\n",
" elif predicted_label == 'B':\n",
" predicted_label = '8'\n",
" if predicted_label not in digits:\n",
" continue\n",
" predictions.append(predicted_label)\n",
" plate_number = ''.join(predictions)\n",
" return plate_number\n",
"\n",
"# Функции для обнаружения номера\n",
"def order_points(pts):\n",
" rect = np.zeros((4, 2), dtype=\"float32\")\n",
" s = pts.sum(axis=1)\n",
" rect[0] = pts[np.argmin(s)]\n",
" rect[2] = pts[np.argmax(s)]\n",
" diff = np.diff(pts, axis=1)\n",
" rect[1] = pts[np.argmin(diff)]\n",
" rect[3] = pts[np.argmax(diff)]\n",
" return rect\n",
"\n",
"def get_transform(image, pts, padding=0.1):\n",
" rect = order_points(pts)\n",
" (tl, tr, br, bl) = rect\n",
" widthA = np.linalg.norm(br - bl)\n",
" widthB = np.linalg.norm(tr - tl)\n",
" maxWidth = max(int(widthA), int(widthB))\n",
" heightA = np.linalg.norm(tr - br)\n",
" heightB = np.linalg.norm(tl - bl)\n",
" maxHeight = max(int(heightA), int(heightB))\n",
" center = np.mean(rect, axis=0)\n",
" vectors = rect - center\n",
" rect_shrinked = rect - vectors * padding\n",
" rect_shrinked[:, 0] = np.clip(rect_shrinked[:, 0], 0, image.shape[1] - 1)\n",
" rect_shrinked[:, 1] = np.clip(rect_shrinked[:, 1], 0, image.shape[0] - 1)\n",
" dst = np.array([\n",
" [0, 0],\n",
" [maxWidth - 1, 0],\n",
" [maxWidth - 1, maxHeight - 1],\n",
" [0, maxHeight - 1]\n",
" ], dtype=\"float32\")\n",
" M = cv2.getPerspectiveTransform(rect_shrinked, dst)\n",
" warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))\n",
" return warped\n",
"\n",
"def get_transformed_plate(image, bbox, padding=0.1):\n",
" plate = get_transform(image, bbox, padding)\n",
" return plate\n",
"\n",
"def process_and_display_plate(image_path, padding=0.1):\n",
" image = cv2.imread(image_path)\n",
" if image is None:\n",
" print(f\"Failed to load image at path: {image_path}\")\n",
" return\n",
" output_image = image.copy()\n",
" img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n",
" ret, thresh = cv2.threshold(img_gray, 100, 200, cv2.THRESH_TOZERO_INV)\n",
" contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)\n",
" plate_found = False\n",
" plate_image = None\n",
" plate_box = None\n",
" for cnt in contours:\n",
" x, y, w, h = cv2.boundingRect(cnt)\n",
" area = w * h\n",
" aspectRatio = float(w) / h\n",
" if aspectRatio >= 3 and area > 600:\n",
" approx = cv2.approxPolyDP(cnt, 0.05 * cv2.arcLength(cnt, True), True)\n",
" if len(approx) <= 4 and x > 15:\n",
" rect = cv2.minAreaRect(cnt)\n",
" box = cv2.boxPoints(rect)\n",
" box = np.intp(box)\n",
" plate_image = get_transformed_plate(image, box, padding)\n",
" plate_found = True\n",
" plate_box = box\n",
" break\n",
" if plate_found:\n",
" cv2.polylines(output_image, [plate_box], isClosed=True, color=(0, 255, 0), thickness=2)\n",
" # Распознавание номера\n",
" plate_number = recognize_plate(plate_image)\n",
" else:\n",
" plate_number = None\n",
"\n",
" height, width = image.shape[:2]\n",
" black_space_width = width // 2\n",
" black_space = np.zeros((height, black_space_width, 3), dtype=np.uint8)\n",
" if plate_found and plate_image is not None:\n",
" plate_height, plate_width = plate_image.shape[:2]\n",
" scale_factor = min(black_space_width / (plate_width + 200), height / plate_height)\n",
" new_plate_width = int(plate_width * scale_factor)\n",
" new_plate_height = int(plate_height * scale_factor)\n",
" resized_plate = cv2.resize(plate_image, (new_plate_width, new_plate_height), interpolation=cv2.INTER_AREA)\n",
" y_offset = (height - new_plate_height) // 2\n",
" black_space[y_offset:y_offset + new_plate_height, 0:new_plate_width] = resized_plate\n",
" # Вывод распознанного номера\n",
" if plate_number:\n",
" placeholder_text = \"Number plate:\"\n",
" decoded_text = plate_number\n",
" else:\n",
" placeholder_text = \"Not found\"\n",
" decoded_text = \"\"\n",
" font = cv2.FONT_HERSHEY_SIMPLEX\n",
" font_scale = 1\n",
" font_color = (255, 255, 255)\n",
" thickness = 2\n",
" line_type = cv2.LINE_AA\n",
" cv2.putText(black_space, placeholder_text, (new_plate_width + 20, y_offset + new_plate_height // 2), \n",
" font, font_scale, font_color, thickness, line_type)\n",
" cv2.putText(black_space, decoded_text, (new_plate_width + 20, y_offset + new_plate_height // 2 + 50), \n",
" font, font_scale, font_color, thickness, line_type)\n",
" else:\n",
" placeholder_text = \"Not found\"\n",
" font = cv2.FONT_HERSHEY_SIMPLEX\n",
" font_scale = 1\n",
" font_color = (0, 0, 255)\n",
" thickness = 2\n",
" line_type = cv2.LINE_AA\n",
" text_size, _ = cv2.getTextSize(placeholder_text, font, font_scale, thickness)\n",
" text_x = (black_space_width - text_size[0]) // 2\n",
" text_y = height // 2\n",
" cv2.putText(black_space, placeholder_text, (text_x, text_y), \n",
" font, font_scale, font_color, thickness, line_type)\n",
" combined_image = np.hstack((output_image, black_space))\n",
" combined_image_rgb = cv2.cvtColor(combined_image, cv2.COLOR_BGR2RGB)\n",
" plt.figure(figsize=(15, 10))\n",
" plt.imshow(combined_image_rgb)\n",
" plt.axis('off')\n",
" plt.title(f'Результат обработки: {image_path}')\n",
" plt.show()\n",
"\n",
"# Обработка изображений\n",
2024-11-29 07:15:25 +01:00
"images = ['img/1.jpg', 'img/2.jpg', 'img/3.jpg']\n",
2024-11-29 02:35:02 +01:00
"\n",
"for img_path in images:\n",
" process_and_display_plate(img_path, padding=0.1)\n"
]
2024-11-29 07:15:25 +01:00
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"0: 480x640 1 , 7.0ms\n",
"Speed: 2.0ms preprocess, 7.0ms inference, 1.0ms postprocess per image at shape (1, 3, 480, 640)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\leonk\\AppData\\Local\\Temp\\ipykernel_6660\\3663620689.py:243: DeprecationWarning: `np.int0` is a deprecated alias for `np.intp`. (Deprecated NumPy 1.24)\n",
" cv2.polylines(output_image, [np.int0(best_plate_box)], isClosed=True, color=(0, 255, 0), thickness=2)\n"
]
},
{
"data": {
"image/png": "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6+zatWvWNI098MAD9j/+x/8YvOcY/SGEEIIjMbgQQnyDOTk5sYsXL5qZ2Ze+9CXr+97e+9732nvf+16a/5lnnrE777zzluV98YtfNLMbGhDG7u6umZn90R/9kZmZvfzlL9+o3l/84het73u777776H8visLMzL7yla+Ymbl8RVHYi170ouj7vfrVr7b3v//9liSJzedze9nLXmb7+/uD1/3rf/2v7ed+7ufs85//vNV1fTP9nnvuGbx2jP4QQgjB0YeGEEJ8A3n88cft8PDQXvziF5vZjX91NzN7z3veYw8++CC95ut5b8XXy3j44Yft0qVL7r/n+ThLe9d1liSJfexjH7Msy9x/397eHuU+X+f8+fP25//8n39O13zkIx+xd73rXfbmN7/ZfvzHf9wuXrxoWZbZ3//7f9++/OUvD14/Rn8IIYTg6ENDCCG+gTz88MNmZjdfYr/+L/xFUQy+VN8qvOnee+81M7OLFy8+axlfv9enP/3pje/T973dc8899pKXvOSW1999991mduMvIH/yryx1Xdsjjzxir3zlK5/1/s+HX/3VX7UXvehF9tGPfjR4jp/6qZ8K8t3qGZ9LfwghhHhuSKMhhBDfID7+8Y/bT//0T9s999xjf+2v/TUzu/Fx8PrXv97+2T/7Z/bkk0+6ay5fvnzz/29tbZmZOSO9Bx980HZ3d+1nf/Zng1AhLOPChQv2ute9zv7Vv/pX9tWvfjXI0/f94H3e+ta3WpZl9r73vS/I//Xrr169amZmDzzwgF24cME+9KEPWVVVN/N8+MMf/oabAH79Ly1/sn7/7b/9N/ud3/mdIN98Pjcz/4zPpT+EEEI8N/QXDSGEGIGPfexj9vnPf96aprGnn37aPv7xj9tv/dZv2d13322//uu/btPp9Gbef/JP/om95jWvsVe84hX27ne/2170ohfZ008/bb/zO79jjz/+uH3qU58ysxtO2VmW2Qc+8AE7PDy0yWRib3jDG+zixYv2wQ9+0N7xjnfYq171Knv7299uFy5csK9+9av2G7/xG/bd3/3d9o//8T82M7Nf/MVftNe85jX2qle9yn7oh37I7rnnHnv00UftN37jN24e/3r//febmdlP/uRP2tvf/nYrisL+0l/6S3bvvffa+9//fvuJn/gJe/TRR+3Nb36z7ezs2COPPGK/9mu/Zj/0Qz9k73nPe6woCnv/+99vP/zDP2xveMMb7K/+1b9qjzzyiP3yL//yc9JobMKb3vQm++hHP2pvectb7I1vfKM98sgj9qEPfci+7du+zU5OTm7mm81m9m3f9m32b/7Nv7GXvOQldvbsWXv5y19uL3/5y6P7QwghxHPkT+/AKyGE+P8+Xz/e9uv/K8uyv3TpUv8X/sJf6H/hF36hPzo6otd9+ctf7t/5znf2ly5d6oui6O+8887+TW96U/+rv/qrQb5//s//ef+iF72oz7LMHXX7iU98on/wwQf7vb29fjqd9vfee2//rne9q//d3/3doIxPf/rT/Vve8pZ+f3+/n06n/bd+67f2733ve4M8P/3TP93feeedfZqm7qjbf/tv/23/mte8pt/a2uq3trb6l770pf3f/Jt/s//DP/zDoIx/+k//aX/PPff0k8mkf+CBB/rf/u3fdsfR3oq77767f+Mb3ziYD8vruq7/2Z/92f7
"text/plain": [
"<Figure size 1000x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\leonk\\AppData\\Local\\Temp\\ipykernel_6660\\3663620689.py:255: DeprecationWarning: `np.int0` is a deprecated alias for `np.intp`. (Deprecated NumPy 1.24)\n",
" box = np.int0(box)\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAxoAAADPCAYAAAByW6dTAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA7MElEQVR4nO3dfdBndV3/8de5/95d93sD7OIqYAq4ZT+REhRQTEUiSxGLqGysYGwCxxopQ8BKu7GRZiyD+EODkZkwyBp1RB1gpizUNDARkBBXd0V297r2uvvenrvfHxs7rvt+vb0WjlH6esw0k+fs+X7P95zP+Zzv2YvruUFd1zVEREREREQaFD7dOyAiIiIiIj949KAhIiIiIiKN04OGiIiIiIg0Tg8aIiIiIiLSOD1oiIiIiIhI4/SgISIiIiIijdODhoiIiIiINE4PGiIiIiIi0jg9aIiIiIiISOP0oCEi8n/U5z//eZxxxhnodrsIggD33nvv071LjfjgBz+IIAjw9a9//X/l64mIyMboQUNEfugFQbCh/7v77ruf7l09JM9zvP71r8fS0hKuu+463HzzzdixY8fTvVv/o6699trDzk+n08Epp5yCq666Cqurq428xy233IK/+Iu/aOS1RER+2MRP9w6IiDzdbr755sP+90033YRPfepTRyw/+eST/yd3y/XII49g165duPHGG/Frv/ZrT/fuPK3++q//Gr1eD+vr6/jkJz+Jd73rXbjzzjvxmc98BkEQPKXXvuWWW/DlL38Zb3nLW5rZWRGRHyJ60BCRH3qXXHLJYf/7nnvuwac+9akjln+3wWCATqfz/dw1au/evQCA2dnZxl6z3++j2+029nr/Uy688EJs2rQJAHDZZZfhda97HW6//Xbcc889eNGLXvQ0752IyA8v/adTIiIbcM455+B5z3sevvCFL+Css85Cp9PB29/+dgDAP/7jP+L888/HcccdhyzLcOKJJ+IP//APUZal+Rpf+cpX8NKXvhSdTgfbtm3Dn/3Znx3xfu973/tw6qmnotPpYG5uDqeddhpuueUWAMAb3/hGnH322QCA17/+9QiCAOecc86hbe+880685CUvQbfbxezsLF7zmtfggQceOOz1n/jPjr7yla/g4osvxtzcHF784hcDAJ75zGfip3/6p3H33XfjtNNOQ7vdxs6dOw/9p2O33347du7ciVarhRe84AX4j//4jyP2/8EHH8SFF16I+fl5tFotnHbaafinf/qnI/7c/fffj5e97GVot9vYvn07/uiP/ghVVW3wrNhe9rKXAQAeffRR+mc2cs7OOeccfOxjH8OuXbsO/edZz3zmMw+tH4/HuOaaa3DSSSchyzIcf/zxeNvb3obxePyU9l9E5AeFfqIhIrJBi4uLOO+88/DzP//zuOSSS7B161YAB3/ZuNfr4a1vfSt6vR7uvPNOXH311VhdXcV73vOew17jwIEDeNWrXoXXvva1uOiii/D3f//3uPLKK7Fz506cd955AIAbb7wRl19+OS688EJcccUVGI1G+NKXvoTPfvazuPjii3HppZdi27ZtePe7343LL78cL3zhCw/ty6c//Wmcd955OOGEE3DttddiOBzife97H84880x88YtfPOyLMnDwQeXZz3423v3ud6Ou60PL/+u//uvQe11yySX48z//c1xwwQW4/vrr8fa3vx1vfvObAQB//Md/jIsuuggPPfQQwvDg313df//9OPPMM7Ft2zb87u/+LrrdLm699Vb87M/+LG677Tb83M/9HADg29/+Nl760peiKIpDf+5v/uZv0G63n9J5euSRRwAACwsL9M9s5Jz9/u//PlZWVrB7925cd911AIBerwcAqKoKP/MzP4N/+Zd/wW/8xm/g5JNPxn/+53/iuuuuw1e/+lV85CMfeUqfQUTkB0ItIiKH+c3f/M36u6fHs88+uwZQX3/99Uf8+cFgcMSySy+9tO50OvVoNDriNW666aZDy8bjcX3MMcfUr3vd6w4te81rXlOfeuqp7j7eddddNYD6wx/+8GHLn//859dbtmypFxcXDy2777776jAM61/+5V8+tOyaa66pAdS/8Au/cMRr79ixowZQ/+u//uuhZXfccUcNoG632/WuXbsOLb/hhhtqAPVdd911aNm5555b79y587DPXlVVfcYZZ9TPfvazDy17y1veUgOoP/vZzx5atnfv3npmZqYGUD/66KPuMXjiMzz00EP1vn376kcffbS+4YYb6izL6q1bt9b9fr+u67r+wAc+cMTrbfScnX/++fWOHTuO+LM333xzHYZh/c///M+HLb/++utrAPVnPvMZd99FRH4Y6D+dEhHZoCzL8Ku/+qtHLP/Ov4FfW1vD/v378ZKXvASDwQAPPvjgYX+21+sd9rsfaZri9NNPx9e+9rVDy2ZnZ7F79258/vOfP6r9e+yxx3DvvffijW98I+bn5w8t/9Ef/VH81E/9FD7+8Y8fsc1ll11mvtYpp5xy2O83/MRP/ASAg/9Z0jOe8Ywjlj+x/0tLS7jzzjtx0UUXHToW+/fvx+LiIl75ylfi4Ycfxp49ewAAH//4x/GTP/mTOP300w+93ubNm/GLv/iLR/W5n/Oc52Dz5s141rOehUsvvRQnnXQSPvaxj7m/P3M058zy4Q9/GCeffDKe+9znHvqM+/fvP/Sfbd11111H9RlERH4Q6T+dEhHZoG3btiFN0yOW33///bjqqqtw5513HpFVXVlZOex/b9++/YgS0tzcHL70pS8d+t9XXnklPv3pT+P000/HSSedhFe84hW4+OKLceaZZ7r7t2vXLgAHv3h/t5NPPhl33HHHEb/w/axnPct8re98mACAmZkZAMDxxx9vLj9w4ACAg//JVV3XeMc73oF3vOMd5mvv3bsX27Ztw65duw49qHwna/89t912G6anp5EkCbZv344TTzzxe25zNOfM8vDDD+OBBx7A5s2bzfVP/LK+iMgPMz1oiIhskPW7A8vLyzj77LMxPT2NP/iDP8CJJ56IVquFL37xi7jyyiuP+MXmKIrM166/4/cjTj75ZDz00EP46Ec/ik984hO47bbb8P73vx9XX3013vnOd37fP5O3n99r/5/4vL/zO7+DV77yleafPemkk452N11nnXXWoerURhztObNUVYWdO3five99r7n+ux/IRER+GOlBQ0TkKbj77ruxuLiI22+/HWedddah5V7xaCO63S7e8IY34A1veAMmkwle+9rX4l3vehd+7/d+D61Wy9zmiX+w76GHHjpi3YMPPohNmzZ93/O1J5xwAgAgSRK8/OUvd//sjh078PDDDx+x3Nr/Jh3NOWP/DseJJ56I++67D+eee+5T/rc6RER+UOl3NEREnoIn/ob/O38iMZlM8P73v/9Jv+bi4uJh/ztNU5xyyimo6xp5ntPtjj32WDz/+c/H3/7t32J5efnQ8i9/+cv45Cc/iVe/+tVPep82asuWLTjnnHNwww034LHHHjti/b59+w79/69+9atxzz334HOf+9xh6z/0oQ99X/fxaM5Zt9s1/1Oqiy66CHv27MGNN954xLrhcIh+v9/gHouI/N+kn2iIiDwFZ5xxBubm5vArv/IruPzyyxEEAW6++ebDvsQerVe84hU45phjcOaZZ2Lr1q144IEH8Jd/+Zc4//zzMTU15W77nve8B+eddx5e9KIX4U1vetOhvO3MzAyuvfbaJ71PR+Ov/uqv8OIXvxg7d+7Er//6r+OEE07A448/jn/7t3/D7t27cd999wEA3va2t+Hmm2/Gq171KlxxxRWH8rY7duw47HdWmnY05+wFL3gB/u7v/g5vfetb8cIXvhC9Xg8XXHABfumXfgm33norLrvsMtx1110488wzUZYlHnzwQdx666244447cNppp33fPoOIyP8FetAQEXkKFhYW8NGPfhS//du/jauuugpzc3O45JJLcO6559LfUfheLr30UnzoQx/Ce9/7Xqyvr2P79u24/PLLcdVVV33PbV/+8pfjE5/4BK655hpcffXVSJIEZ599Nv70T/+U/uJ300455RT8+7//O975znfigx/8IBY
"text/plain": [
"<Figure size 1000x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1500x1000 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"0: 480x640 1 , 8.0ms\n",
"Speed: 2.0ms preprocess, 8.0ms inference, 1.0ms postprocess per image at shape (1, 3, 480, 640)\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAxoAAAGZCAYAAAAO+0cNAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAACpTUlEQVR4nO39eaxtWXnejb6zXWvttXZz2jpVp/qGgnIVbX3gLwZMcJJyLsQClBBQAkGWsC1FjqwrfBXHIoYYOyKRY9lKAnEak1vcPyI7WLHD5cb+Ag75rgnuYvqirSqo/nS7Xd3s7h8nlDye96mao3YmMffT85OQmKPGGnPM0c559vuMJ+m6rjMhhBBCCCGEGJD0z7oCQgghhBBCiP/roQ8NIYQQQgghxODoQ0MIIYQQQggxOPrQEEIIIYQQQgyOPjSEEEIIIYQQg6MPDSGEEEIIIcTg6ENDCCGEEEIIMTj60BBCCCGEEEIMjj40hBBCCCGEEIOjDw0hhBDfMV7zmtfYa17zmu/a8oQQQnzn0IeGEEL8T/ChD33IkiR5+n/j8diuu+46u+++++yXf/mX7eDg4Nhlf/GLX7T3vOc99tBDDw1XYcLv/d7v2Xve8x7b3d39jt7n2bj55puDdjx79qy96lWvst/4jd8YpPz5fG7vec977Hd/93cHKU8IIUQ/+tAQQogB+Af/4B/Y/fffbx/4wAfsx3/8x83M7Cd+4ifsnnvusc9+9rPHKvOLX/yivfe97/1f8qHx3ve+98/0Q8PM7MUvfrHdf//9dv/999u73vUue+yxx+xNb3qTffCDH/yfLns+n9t73/tefWgIIcT/QvI/6woIIcT/FfjLf/kv27333vv09U/91E/Zxz/+cXv9619vP/RDP2Rf+tKXbDKZ/BnW8Luf8+fP29/8m3/z6eu3v/3tdvvtt9sv/uIv2o/92I/9GdZMCCHEcdBfNIQQ4jvEa1/7Wnv3u99tDz/8sH34wx8O/tsDDzxgf/Wv/lU7efKkjcdju/fee+03f/M3n/7vH/rQh+yv/bW/ZmZmf/7P//mnQ4r+9L/If+xjH7NXvepVNp1ObXNz0173utfZF77wBVePBx54wN785jfbmTNnbDKZ2J133mk//dM/bWZm73nPe+wnf/Inzczslltuefo+f/qvKB/+8IftZS97mU0mEzt58qS95S1vsW9961vuPr/yK79it912m00mE3v5y19u//W//tdjt52Z2blz5+wFL3iBPfjgg8+YZ71e29//+3/fXvayl9n29rZNp1N71ateZZ/4xCeezvPQQw/ZmTNnzMzsve9979PP+J73vOfpPH39IYQQ4rmjDw0hhPgO8ra3vc3MzH77t3/76bQvfOEL9r3f+732pS99yf7u3/279gu/8As2nU7tDW94w9OahFe/+tX2d/7O3zEzs7/39/7e0yFFL3jBC8zM7P7777fXve51NpvN7P3vf7+9+93vti9+8Yv2yle+MvhI+OxnP2uveMUr7OMf/7i9853vtF/6pV+yN7zhDfZbv/VbZmb2pje9yd761reamdkv/uIvPn2fb7+Y/9zP/Zy9/e1vtzvuuMP+yT/5J/YTP/ET9p//83+2V7/61UGo1b/+1//afvRHf9TOnTtn/+gf/SP7vu/7PvuhH/oh+kESS1VV9q1vfctOnTr1jHn29/ftX/2rf2Wvec1r7P3vf7+95z3vsQsXLth9991nf/Inf2JmZmfOnLEPfOADZmb2xje+8elnfNOb3hTdH0IIIY5BJ4QQ4tj86q/+amdm3R/8wR88Y57t7e3uJS95ydPXP/ADP9Ddc8893XK5fDqtbdvuz/25P9fdcccdT6f92q/9Wmdm3Sc+8YmgvIODg25nZ6d75zvfGaQ/8cQT3fb2dpD+6le/utvc3OwefvjhIG/btk///3/8j/9xZ2bdgw8+GOR56KGHuizLup/7uZ8L0j/3uc91eZ4/nb5er7uzZ892L37xi7vVavV0vl/5lV/pzKz7/u///mdsm29z0003dX/pL/2l7sKFC92FCxe6z3zmM91b3vKWzsy6H//xH3863/d///cH5dV1Hdyz67ruypUr3TXXXNP98A//8NNpFy5c6Mys+5mf+Rl379j+EEII8dzQXzSEEOI7zGw2e/r0qcuXL9vHP/5xe/Ob32wHBwd28eJFu3jxol26dMnuu+8+++pXv2qPPvros5b3O7/zO7a7u2tvfetbn/79xYsXLcsye8UrXvF02NCFCxfsk5/8pP3wD/+w3XjjjUEZSZL01vsjH/mItW1rb37zm4P7nDt3zu64446n7/OHf/iH9tRTT9mP/diPWVmWT//+He94h21vb0e302//9m/bmTNn7MyZM/aiF73Ifu3Xfs3e9ra32fvf//5n/E2WZU/fs21bu3z5stV1bffee6/98R//ce89h+gPIYQQHInBhRDiO8zh4aGdPXvWzMy+9rWvWdd19u53v9ve/e530/xPPfWUnT9//hnL++pXv2pmVzUgjK2tLTMz+8Y3vmFmZnffffex6v3Vr37Vuq6zO+64g/73oijMzOzhhx82M3P5iqKwW2+9Nfp+r3jFK+x973ufJUliGxsb9oIXvMB2dnZ6f/dv/+2/tV/4hV+wBx54wKqqejr9lltu6f3tEP0hhBCCow8NIYT4DvLII4/Y3t6e3X777WZ29V/dzcze9a532X333Ud/8+28z8S3y7j//vvt3Llz7r/n+TBLe9u2liSJfexjH7Msy9x/n81mg9zn25w+fdr+wl/4C8/pNx/+8IftHe94h73hDW+wn/zJn7SzZ89almX2D//hP7Svf/3rvb8foj+EEEJw9KEhhBDfQe6//34zs6dfYr/9L/xFUfS+VD9TeNNtt91mZmZnz5591jK+fa/Pf/7zx75P13V2yy232POe97xn/P1NN91kZlf/AvKn/8pSVZU9+OCD9qIXvehZ7/8/w6//+q/brbfeah/5yEeC5/iZn/mZIN8zPeNz6Q8hhBDPDWk0hBDiO8THP/5x+9mf/Vm75ZZb7G/8jb9hZlc/Dl7zmtfYv/gX/8Ief/xx95sLFy48/f+n06mZmTPSu++++2xra8t+/ud/PggVwjLOnDljr371q+3f/Jt/Y9/85jeDPF3X9d7nTW96k2VZZu9973uD/N/+/aVLl8zM7N5777UzZ87YBz/4QVuv10/n+dCHPvQdNwH89l9a/nT9Pv3pT9unPvWpIN/GxoaZ+Wd8Lv0hhBDiuaG/aAghxAB87GMfswceeMDqurYnn3zSPv7xj9vv/M7v2E033WS/+Zu/aePx+Om8/+yf/TN75Stfaffcc4+9853vtFtvvdWefPJJ+9SnPmWPPPKIfeYznzGzq07ZWZbZ+9//ftvb27PRaGSvfe1r7ezZs/aBD3zA3va2t9lLX/pSe8tb3mJnzpyxb37zm/bRj37Uvu/7vs/+6T/9p2Zm9su//Mv2yle+0l760pfaj/zIj9gtt9xiDz30kH30ox99+vjXl73sZWZm9tM//dP2lre8xYqisL/yV/6K3Xbbbfa+973Pfuqnfsoeeughe8Mb3mCbm5v24IMP2m/8xm/Yj/zIj9i73vUuK4rC3ve+99mP/uiP2mtf+1r763/9r9uDDz5ov/qrv/qcNBrH4fWvf7195CMfsTe+8Y32ute9zh588EH74Ac/aHfddZcdHh4+nW8ymdhdd91l/+7f/Tt73vOeZydPnrS7777b7r777uj+EEII8Rz5szvwSggh/v+fbx9v++3/lWXZnTt3rvuLf/Evdr/0S7/U7e/v0999/etf797+9rd3586d64qi6M6fP9+9/vWv73791389yPcv/+W/7G699dYuyzJ31O0nPvGJ7r777uu2t7e78Xjc3Xbbbd073vGO7g//8A+DMj7/+c93b3zjG7udnZ1uPB53d955Z/fud787yPOzP/uz3fnz57s0Td1Rt//+3//77pWvfGU3nU676XTaPf/5z+/+9t/+292Xv/zloIx//s//eXfLLbd0o9Gou/fee7tPfvKT7jjaZ+Kmm27qXve61/Xmw/Latu1+/ud/vrvpppu60WjUveQ
"text/plain": [
"<Figure size 1000x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAxoAAADYCAYAAABsiJVwAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABBz0lEQVR4nO3de5AldX338U93n+4+t5k5M7Nz2Ruz7AVc1k2RiKiggGJUJMREERNCElMmgTIVsExKEoOASTQXU5IqEwPhDw2UVAUDMSn1EbWAehIjxqigItcVFlj2NrNzPde+PX9snHKz38+PWWnDo35eVVZJn/2d06f7192nd/a8xyuKooCIiIiIiEiJ/Bd6BURERERE5MePbjRERERERKR0utEQEREREZHS6UZDRERERERKpxsNEREREREpnW40RERERESkdLrREBERERGR0ulGQ0RERERESqcbDRERERERKZ1uNEREfkR99atfxVlnnYVGowHP83D//fe/0KtUio9//OPwPA9PPvnk/5fPJyIia6MbDRH5ied53pr+d++9977Qq7oqSRK89a1vxZEjR3DDDTfg1ltvxczMzAu9Wv+rrr/++mP2T71ex2mnnYZrrrkGS0tLpbzGbbfdhr/+678u5blERH7SVF7oFRAReaHdeuutx/z3Lbfcgi984QvHLd+5c+f/5mo57dmzB3v37sXNN9+M3/zN33yhV+cF9Xd/93doNptYWVnB5z//eXzgAx/A3XffjS996UvwPO95Pfdtt92Gb3/723jXu95VzsqKiPwE0Y2GiPzEu+yyy4757/vuuw9f+MIXjlv+P3U6HdTr9R/mqlGHDh0CALRardKes91uo9FolPZ8/1suvvhirFu3DgBwxRVX4C1veQvuvPNO3HfffXjFK17xAq+diMhPLv3TKRGRNTjvvPPw4he/GF/72tdwzjnnoF6v473vfS8A4F/+5V9w4YUXYsOGDYjjGNu2bcOf/MmfIMsy8zm+853v4NWvfjXq9To2btyIv/zLvzzu9T7ykY9g165dqNfrGB0dxRlnnIHbbrsNAPD2t78d5557LgDgrW99KzzPw3nnnbc69u6778arXvUqNBoNtFotvOlNb8JDDz10zPN/758dfec738Gll16K0dFRvPKVrwQAbNmyBT/3cz+He++9F2eccQZqtRp27969+k/H7rzzTuzevRvVahUveclL8I1vfOO49X/44Ydx8cUXY2xsDNVqFWeccQb+9V//9bg/9+CDD+I1r3kNarUaNm3ahD/90z9Fnudr3Cu217zmNQCAJ554gv6Zteyz8847D5/5zGewd+/e1X+etWXLltXH+/0+rrvuOmzfvh1xHGPz5s14z3veg36//7zWX0Tkx4V+oiEiskZzc3O44IIL8Eu/9Eu47LLLMDU1BeDol42bzSbe/e53o9ls4u6778a1116LpaUlfOhDHzrmOebn5/GGN7wBb37zm3HJJZfgn/7pn3D11Vdj9+7duOCCCwAAN998M6688kpcfPHFuOqqq9Dr9fDNb34TX/nKV3DppZfi8ssvx8aNG/HBD34QV155JV760peurssXv/hFXHDBBdi6dSuuv/56dLtdfOQjH8HZZ5+Nr3/968d8UAaO3qjs2LEDH/zgB1EUxeryxx9/fPW1LrvsMvzVX/0VLrroItx4441473vfi3e+850AgD/7sz/DJZdcgkceeQS+f/Tvrh588EGcffbZ2LhxI/7gD/4AjUYDt99+O37hF34Bd9xxB37xF38RAHDgwAG8+tWvRpqmq3/u7//+71Gr1Z7XftqzZw8AYHx8nP6ZteyzP/qjP8Li4iKeeeYZ3HDDDQCAZrMJAMjzHD//8z+Pf//3f8dv//ZvY+fOnfjWt76FG264AY8++ig+9alPPa/3ICLyY6EQEZFj/M7v/E7xP0+P5557bgGguPHGG4/7851O57hll19+eVGv14ter3fcc9xyyy2ry/r9fjE9PV285S1vWV32pje9qdi1a5dzHe+5554CQPHJT37ymOWnn356MTk5WczNza0ue+CBBwrf94tf+7VfW1123XXXFQCKX/7lXz7uuWdmZgoAxX/8x3+sLrvrrrsKAEWtViv27t27uvymm24qABT33HPP6rLzzz+/2L179zHvPc/z4qyzzip27Nixuuxd73pXAaD4yle+srrs0KFDxcjISAGgeOKJJ5zb4Hvv4ZFHHikOHz5cPPHEE8VNN91UxHFcTE1NFe12uyiKovjYxz523POtdZ9deOGFxczMzHF/9tZbby183y/+7d/+7ZjlN954YwGg+NKXvuRcdxGRnwT6p1MiImsUxzF+4zd+47jl3/838MvLy5idncWrXvUqdDodPPzww8f82Wazecx3P6Iowplnnonvfve7q8tarRaeeeYZfPWrXz2h9du/fz/uv/9+vP3tb8fY2Njq8p/6qZ/Cz/7sz+Kzn/3scWOuuOIK87lOO+20Y77f8LKXvQzA0X+WdNJJJx23/Hvrf+TIEdx999245JJLVrfF7Ows5ubm8PrXvx6PPfYY9u3bBwD47Gc/i5e//OU488wzV59vYmICv/Irv3JC7/vUU0/FxMQETj75ZFx++eXYvn07PvOZzzi/P3Mi+8zyyU9+Ejt37sSLXvSi1fc4Ozu7+s+27rnnnhN6DyIiP470T6dERNZo48aNiKLouOUPPvggrrnmGtx9993HZVUXFxeP+e9NmzYdV0IaHR3FN7/5zdX/vvrqq/HFL34RZ555JrZv347Xve51uPTSS3H22Wc712/v3r0Ajn7w/p927tyJu+6667gvfJ988snmc33/zQQAjIyMAAA2b95sLp+fnwdw9J9cFUWB973vfXjf+95nPvehQ4ewceNG7N27d/VG5ftZ6+9yxx13YHh4GGEYYtOmTdi2bdtzjjmRfWZ57LHH8NBDD2FiYsJ8/Htf1hcR+UmmGw0RkTWyvjuwsLCAc889F8PDw/jjP/5jbNu2DdVqFV//+tdx9dVXH/fF5iAIzOcuvu/7ETt37sQjjzyCT3/60/jc5z6HO+64Ax/96Edx7bXX4v3vf/8P/T251vO51v977/f3f//38frXv978s9u3bz/R1XQ655xzVqtTa3Gi+8yS5zl2796ND3/4w+bj//OGTETkJ5FuNEREnod7770Xc3NzuPPOO3HOOeesLncVj9ai0WjgbW97G972trdhMBjgzW9+Mz7wgQ/gD//wD1GtVs0x3/uFfY888shxjz388MNYt27dDz1fu3XrVgBAGIZ47Wtf6/yzMzMzeOyxx45bbq1/mU5kn7Hfw7Ft2zY88MADOP/885/37+oQEflxpe9oiIg8D9/7G/7v/4nEYDDARz/60R/4Oefm5o757yiKcNppp6EoCiRJQsetX78ep59+Ov7hH/4BCwsLq8u//e1v4/Of/zze+MY3/sDrtFaTk5M477zzcNNNN2H//v3HPX748OHV///GN74R9913H/7zP//zmMc/8YlP/FDX8UT2WaPRMP8p1SWXXIJ9+/bh5ptvPu6xbreLdrtd4hqLiPxo0k80RESeh7POOgujo6P49V//dVx55ZXwPA+33nrrMR9iT9TrXvc6TE9P4+yzz8bU1BQeeugh/M3f/A0uvPBCDA0NOcd+6EMfwgUXXIBXvOIVeMc73rGatx0ZGcH111//A6/Tifjbv/1bvPKVr8Tu3bvxW7/1W9i6dSsOHjyIL3/5y3jmmWfwwAMPAADe85734NZbb8Ub3vAGXHXVVat525mZmWO+s1K2E9lnL3nJS/CP//iPePe7342XvvSlaDabuOiii/Crv/qruP3223HFFVfgnnvuwdlnn40sy/Dwww/j9ttvx1133YUzzjjjh/YeRER+FOhGQ0TkeRgfH8enP/1p/N7v/R6uueYajI6O4rLLLsP5559Pv6PwXC6//HJ84hOfwIc//GGsrKxg06ZNuPLKK3HNNdc859jXvva1+NznPofrrrsO1157LcIwxLnnnou/+Iu/oF/8Lttpp52G//qv/8L73/9+fPzjH8fc3BwmJyfx0z/907j22mtX/9z69etxzz334Hd
"text/plain": [
"<Figure size 1000x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1500x1000 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"0: 480x640 1 , 7.8ms\n",
"Speed: 1.0ms preprocess, 7.8ms inference, 1.0ms postprocess per image at shape (1, 3, 480, 640)\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAxoAAAHMCAYAAABSuN5JAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAACLl0lEQVR4nO39a6xuZ3mfiz/jHe9xntZcy17LNiYxtkNSCOQEu0QNEEoPVgWNALWUqIWiSCSRqlT5QKSm2TSmIemmVRolagtND6EyX6qkIKWN0D/5F6pUO1FVdhXSBGiA2BiDsZfXWnOd5pzvYYyxP7gsxb6vN9xrvsOAva9LihQexjsOz3ieZ4yxJtf9q7qu64qIiIiIiEiPDL7eJyAiIiIiIs89/NAQEREREZHe8UNDRERERER6xw8NERERERHpHT80RERERESkd/zQEBERERGR3vFDQ0REREREescPDRERERER6R0/NEREREREpHf80BARkWeM17zmNeU1r3nNN+z+RETkmcMPDRGRDfjABz5Qqqq68X/T6bQ873nPK/fdd1/5pV/6pXL16tUT7/uTn/xkuf/++8tDDz3U3wkDv/M7v1Puv//+cnBw8Iwe50/jBS94wVP68dy5c+VVr3pV+fCHP9zL/g8PD8v9999f/st/+S+97E9ERL46fmiIiPTAP/yH/7A88MAD5X3ve1/5sR/7sVJKKT/+4z9eXvrSl5bf//3fP9E+P/nJT5Z3v/vdX5MPjXe/+91f1w+NUkr5ru/6rvLAAw+UBx54oLzzne8sX/rSl8qb3vSm8v73v3/jfR8eHpZ3v/vdfmiIiHwNGX69T0BE5LnAX/krf6W8/OUvv/Gff/Inf7J89KMfLa9//evLD/zAD5RPfepTZTabfR3P8BufO++8s/ytv/W3bvznt73tbeVbvuVbyi/8wi+UH/3RH/06npmIiJwE/6IhIvIM8drXvra8613vKp///OfLBz/4waf8d5/+9KfLX/trf62cOXOmTKfT8vKXv7z8+q//+o3//gMf+ED563/9r5dSSvnzf/7P3/ifFP3Jf5H/yEc+Ul71qleV7e3tsru7W173uteVP/zDPwzn8elPf7q8+c1vLmfPni2z2ax827d9W/mpn/qpUkop999/f/mJn/iJUkopd999943j/Mm/onzwgx8sL3vZy8psNitnzpwpb3nLW8oXvvCFcJxf/uVfLvfee2+ZzWblz/7ZP1v+63/9ryfuu1JKuf3228uLXvSi8uCDD67dZrFYlH/wD/5BednLXlZOnTpVtre3y6te9arysY997MY2Dz30UDl79mwppZR3v/vdN67x/vvvv7HNV7sfIiJy8/ihISLyDPLWt761lFLKb/7mb95o+8M//MPyvd/7veVTn/pU+Xt/7++Vn//5ny/b29vlDW94ww0n4dWvfnX5u3/375ZSSvn7f//v3/ifFL3oRS8qpZTywAMPlNe97nVlZ2envPe97y3vete7yic/+cnyyle+8ikfCb//+79fXvGKV5SPfvSj5R3veEf5xV/8xfKGN7yh/Mf/+B9LKaW86U1vKj/4gz9YSinlF37hF24c5ysv5j/7sz9b3va2t5UXvvCF5Z/+039afvzHf7z85//8n8urX/3qp/xPrf7Nv/k35Ud+5EfK7bffXv7xP/7H5fu+7/vKD/zAD+AHSZblclm+8IUvlFtuuWXtNleuXCn/+l//6/Ka17ymvPe97y33339/OX/+fLnvvvvK7/3e75VSSjl79mx53/veV0op5Y1vfOONa3zTm96Uvh8iInICOhEROTG/8iu/0pVSuv/+3//72m1OnTrVffd3f/eN//wX/sJf6F760pd2x8fHN9ratu3+3J/7c90LX/jCG22/+qu/2pVSuo997GNP2d/Vq1e7/f397h3veMdT2r/85S93p06dekr7q1/96m53d7f7/Oc//5Rt27a98f//k3/yT7pSSvfggw8+ZZuHHnqoq+u6+9mf/dmntP/P//k/u+FweKN9sVh0586d677ru76rm8/nN7b75V/+5a6U0n3/93//2r75CnfddVf3l//yX+7Onz/fnT9/vvvEJz7RveUtb+lKKd2P/diP3dju+7//+5+yv9Vq9ZRjdl3XXbp0qbvtttu6H/qhH7rRdv78+a6U0v30T/90OHb2foiIyM3hXzRERJ5hdnZ2blSfunjxYvnoRz9a3vzmN5erV6+WJ554ojzxxBPlwoUL5b777iuf+cxnyhe/+MU/dX+/9Vu/VQ4ODsoP/uAP3vj9E088Ueq6Lq94xStu/M+Gzp8/X377t3+7/NAP/VD55m/+5qfso6qqr3reH/rQh0rbtuXNb37zU45z++23lxe+8IU3jvPxj3+8PP744+VHf/RHy3g8vvH7t7/97eXUqVPpfvrN3/zNcvbs2XL27Nnynd/5neVXf/VXy1vf+tby3ve+d+1v6rq+ccy2bcvFixfLarUqL3/5y8v/+B//46ses4/7ISIijDK4iMgzzLVr18q5c+dKKaV89rOfLV3XlXe9613lXe96F27/+OOPlzvvvHPt/j7zmc+UUp50QIi9vb1SSil//Md/XEop5SUvecmJzvszn/lM6bquvPCFL8T/fjQalVJK+fznP19KKWG70WhU7rnnnvTxXvGKV5T3vOc9paqqsrW1VV70oheV/f39r/q7f/fv/l35+Z//+fLpT3+6LJfLG+133333V/1tH/dDREQYPzRERJ5BHnnkkXL58uXyLd/yLaWUJ//VvZRS3vnOd5b77rsPf/OVbdfxlX088MAD5fbbbw///XDYz9Letm2pqqp85CMfKXVdh/9+Z2enl+N8hVtvvbX8xb/4F2/qNx/84AfL29/+9vKGN7yh/MRP/EQ5d+5cqeu6/KN/9I/K5z73ua/6+z7uh4iIMH5oiIg8gzzwwAOllHLjJfYr/8I/Go2+6kv1uv9507333ltKKeXcuXN/6j6+cqw/+IM/OPFxuq4rd999d/nWb/3Wtb+/6667SilP/gXkT/6VZblclgcffLB853d+5596/E34tV/7tXLPPfeUD33oQ0+5jp/+6Z9+ynbrrvFm7oeIiNwcOhoiIs8QH/3oR8vP/MzPlLvvvrv8zb/5N0spT34cvOY1ryn/8l/+y/Loo4+G35w/f/7G/7+9vV1KKSFI77777it7e3vl537u557yPxV6+j7Onj1bXv3qV5d/+2//bXn44Yefsk3XdV/1OG9605tKXdfl3e9+91O2/8rvL1y4UEop5eUvf3k5e/Zsef/7318Wi8WNbT7wgQ884yGAX/lLy588v//23/5b+d3f/d2nbLe1tVVKidd4M/dDRERuDv+iISLSAx/5yEfKpz/96bJarcpjjz1WPvrRj5bf+q3fKnfddVf59V//9TKdTm9s+8//+T8vr3zlK8tLX/rS8o53vKPcc8895bHHHiu/+7u/Wx555JHyiU98opTyZFJ2Xdflve99b7l8+XKZTCblta99bTl37lx53/veV9761reW7/me7ylvectbytmzZ8vDDz9cfuM3fqN83/d9X/ln/+yflVJK+aVf+qXyyle+snzP93xP+eEf/uFy9913l4ceeqj8xm/8xo3yry972ctKKaX81E/9VHnLW95SRqNR+at/9a+We++9t7znPe8pP/mTP1keeuih8oY3vKHs7u6WBx98sHz4wx8uP/zDP1ze+c53ltFoVN7znveUH/mRHymvfe1ry9/4G3+jPPjgg+VXfuVXbsrROAmvf/3ry4c+9KHyxje+sbzuda8rDz74YHn/+99fXvziF5dr167d2G42m5UXv/jF5d//+39fvvVbv7WcOXOmvOQlLykveclL0vdDRERukq9fwSsRkWc/Xylv+5X/G4/H3e233979pb/0l7pf/MVf7K5cuYK/+9znPte97W1v626//fZuNBp1d955Z/f617+++7Vf+7WnbPev/tW/6u65556urutQ6vZjH/tYd99993WnTp3qptNpd++993Zvf/vbu49//ONP2ccf/MEfdG984xu7/f39bjqddt/2bd/Wvetd73rKNj/zMz/T3Xnnnd1gMAi
"text/plain": [
"<Figure size 1000x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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m7rlllvu9W8XFhbu9d2PVqulRz3qUfr3f//3E8uWl5d155136rOf/ey2tu+uu+7S5z//eb3whS/Url27Tiz/gR/4Af3Ij/yIPvzhD5+0ztVXXx0+14UXXniv7zf80A/9kKTj/1nSAx7wgJOWf2v7jxw5ohtvvFFXXHHFiX1x6NAhHT58WE996lN122236Rvf+IYk6cMf/rB++Id/WI961KNOPN/evXv10z/909t63w95yEO0d+9ePehBD9JVV12l888/Xx/60IfS789s55hF3vve9+qCCy7QQx/60BPv8dChQyf+s62bbrppW+8BAL4b8Z9OAcAWnXXWWWq1Wict//KXv6xrr71WN95440lZ1WPHjt3rf5999tknlZB27typL37xiyf+9yte8Qp94hOf0KMe9Sidf/75espTnqIXvOAFuuSSS9Ltu+OOOyQd/+D9X11wwQX66Ec/etIXvh/0oAeFz/WfbyYkaceOHZKkc845J1x+9OhRScf/k6uyLPWqV71Kr3rVq8LnPnDggM466yzdcccdJ25U/rNo+zPve9/7tLS0pGazqbPPPlvnnXfefa6znWMWue2223TzzTdr79694ePf+rI+AHwv40YDALYo+u7AysqKLr30Ui0tLem3fuu3dN5556nT6ehzn/ucXvGKV5z0xeZ6vR4+d/mfvh9xwQUX6NZbb9UHP/hBfeQjH9H73vc+vfnNb9Z1112n1772td/295Rt531t/7fe76/92q/pqU99avhvzz///O1uZurxj3/8ierUVmz3mEXm87kuuugivfGNbwwf/683ZADwvYgbDQC4Hz75yU/q8OHDev/736/HP/7xJ5ZnxaOt6Pf7ev7zn6/nP//5Go/Hevazn63Xve51+o3f+A11Op1wnW/9wb5bb731pMduueUW7dmz59uerz333HMlSc1mU09+8pPTf7t//37ddtttJy2Ptr9K2zlm7u9wnHfeefrCF76gJz3pSff7b3UAwHcrvqMBAPfDt37C/59/IzEej/XmN7/5lJ/z8OHD9/rfrVZLF154ocqy1GQyseudccYZevjDH64///M/18rKyonlX/rSl/Sxj31MT3/60095m7Zq3759uuyyy/TWt75Vd91110mPHzx48MT///SnP12f/vSn9Y//+I/3evxd73rXt3Ubt3PM+v1++J9SXXHFFfrGN76ht73tbSc9NhgMtLGxUeEWA8D/TPxGAwDuh8c85jHauXOnfu7nfk7XXHONiqLQDTfccK8Psdv1lKc8RaeffrouueQSnXbaabr55pv1x3/8x3rGM56hxcXFdN03vOENuvzyy/XoRz9aL3rRi07kbXfs2KHXvOY1p7xN2/Enf/IneuxjH6uLLrpIv/iLv6hzzz1X99xzj/7hH/5Bd955p77whS9Ikl7+8pfrhhtu0NOe9jS95CUvOZG33b9//72+s1K17RyzRzziEfqLv/gLvexlL9MjH/lILSws6JnPfKZ+5md+Ru95z3t09dVX66abbtIll1yi2WymW265Re95z3v00Y9+VBdffPG37T0AwP8E3GgAwP2we/duffCDH9Sv/uqv6tprr9XOnTt15ZVX6klPepL9jsJ9ueqqq/Sud71Lb3zjG7W+vq6zzz5b11xzja699tr7XPfJT36yPvKRj+jVr361rrvuOjW
"text/plain": [
"<Figure size 1000x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABJ4AAAJvCAYAAAA6DRtsAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOz9ebRtV1nmj39ms5q9T3PvTU9IaAyCUCIo0qhECFCJoCBKU2CDYIPNEMGBfgVRCKDSCCWKBkdRCoIMaRyiVkGkx9JSC1Cx5wdEAhhIc9tzzm7Wmt3vj3fOtfe5SSBAQnJxPYxD7jlnn71XO9d8n/k8z6tSSokRI0aMGDFixIgRI0aMGDFixIgRI25m6Ft7A0aMGDFixIgRI0aMGDFixIgRI0Z8ZWIknkaMGDFixIgRI0aMGDFixIgRI0bcIhiJpxEjRowYMWLEiBEjRowYMWLEiBG3CEbiacSIESNGjBgxYsSIESNGjBgxYsQtgpF4GjFixIgRI0aMGDFixIgRI0aMGHGLYCSeRowYMWLEiBEjRowYMWLEiBEjRtwiGImnESNGjBgxYsSIESNGjBgxYsSIEbcIRuJpxIgRI0aMGDFixIgRI0aMGDFixC2CkXgaMWLEiBEjRowYMWLEiBEjRowYcYtgJJ5GjBgxYsSIEbcolFJceumlt/Zm3Cbx4Ac/mAc/+ME3+/s++clP5k53utPN/r63Jm6pYzVixIgRI0aMuGUxEk8jRowYMWLELYzXvva1KKWGr7Ztuetd78pP/uRPcs0119zam/cViyuvvHLfcddac9ppp/Hwhz+cv/7rv761N+8G8ZnPfIZLL72UD3/4w7f2ptwsuM997sNP/MRPAPDWt76VSy65hHPPPZemaTjvvPN47GMfyz//8z/fyls5YsSIESNGjLglYW/tDRgxYsSIESP+s+AFL3gBd77znVkul/zlX/4lr3rVq3j729/OP//zPzOdTm/tzbvFsFgssPbWm3I88YlP5BGPeAQhBD760Y9y2WWXcdFFF/HBD36Qe97znrfadt0QPvOZz/D85z+fO93pTtz73vf+ot/n1a9+NTHGm2/Dvgh89rOf5e///u95wQteAMA//dM/cejQIZ7+9KdzxhlncPXVV/O7v/u73O9+9+Ov//qvude97vU53++d73znl2OzR4wYMWLEiBE3M0biacSIESNGjPgy4eEPfzjf+I3fCMAP//APc/rpp/Pf//t/50/+5E944hOfeIN/M5vN2NjY+HJu5s2Otm1v1c//hm/4Br7v+75v+P7CCy/k4Q9/OK961au47LLLbsUtu+VQVdWtvQlcfvnltG3LQx7yEACe+9znXu81P/zDP8x5553Hq171Kn77t3/7c75fXde3yHaOGDFixIgRI25ZjFa7ESNGjBgx4lZCKcg/8YlPAJLLs7m5yRVXXMEjHvEItra2+N7v/V5ACKhnPvOZnH/++TRNw93udjde9rKXkVK63vv+/u//Pve73/2YTqccOnSIb/3Wb72eWuTyyy/nwgsvZGNjg62tLb7927+df/mXf9n3mquvvpqnPOUpnHfeeTRNw+1udzu+8zu/kyuvvHJ4zYc+9CEuueQSzjjjDCaTCXe+8535wR/8wX3vc3LG06WXXopSio9//OM8+clP5uDBgxw4cICnPOUpzOfzfX+7WCz4qZ/6Kc444wy2trZ41KMexVVXXfUl5UZdeOGFAFxxxRX7fn78+HGe8YxnDMf4Lne5Cy95yUuupxx64xvfyH3ucx+2trbY3t7mnve8J7/+679+vf07GcVyuX781vH+97+f+973vgA85SlPGSyCr33tawGYz+d85CMf4fDhw593H0/OeCq2w5e97GX81m/9Fl/1VV/FdDrl4osv5tOf/jQpJV74whdy3nnnMZlM+M7v/E6OHj267z1jjFx66aWce+65TKdTLrroIv71X/+VO93pTjz5yU++3ja87W1v46KLLmIymdzodp511llMp1OOHz/+effp5Iyn97///SileNOb3sTP//zPc84557CxscGjHvUoPv3pT1/v78t+TyYT7ne/+/EXf/EXY27UiBEjRowY8WXAqHgaMWLEiBEjbiUU4uP0008ffua955JLLuGBD3wgL3vZy5hOp6SUeNSjHsX73vc+fuiHfoh73/vevOMd7+Bnf/Znueqqq/i1X/u14e+f//znc+mll/LN3/zNvOAFL6Cua/7f//t/vPe97+Xiiy8G4PWvfz0/8AM/wCWXXMJLXvIS5vM5r3rVq3jgAx/I3//93w+ExWMe8xj+5V/+hac97Wnc6U534tprr+Vd73oXn/rUp4bvL774Ys4880ye9axncfDgQa688kr+6I/+6Cbt/+Mf/3jufOc786IXvYi/+7u/43/+z//JWWedxUte8pLhNU9+8pN585vfzPd///fzgAc8gD//8z/n27/927+k416In0OHDg0/m8/nPOhBD+Kqq67iR3/0R7nDHe7AX/3VX/HsZz+bz372s7ziFa8A4F3vehdPfOITeehDHzps57/927/xf//v/+XpT3/6l7Rdd7/73XnBC17Ac5/7XJ761KcOBNk3f/M3A/CBD3yAiy66iOc973lfNOn2hje8gb7vedrTnsbRo0d56UtfyuMf/3ge8pCH8P73v5+f+7mf4+Mf/zivfOUr+Zmf+Rl+93d/d/jbZz/72bz0pS/lkY98JJdccgn/8A//wCWXXMJyubze5zjnePe7382v/MqvXO93x48fxznH1VdfzSte8Qp2dnZ46EMf+kXtD8Av//Ivo5Ti537u57j22mt5xStewcMe9jA+/OEPD6TXq171Kn7yJ3+SCy+8kJ/+6Z/myiuv5NGPfjSHDh3ivPPO+6I/e8SIESNGjBhxE5BGjBgxYsSIEbcoXvOa1yQgvfvd707XXXdd+vSnP53e+MY3ptNPPz1NJpP0H//xHymllH7gB34gAelZz3rWvr//4z/+4wSkX/qlX9r388c+9rFJKZU+/vGPp5RS+tjHPpa01um7vuu7Ughh32tjjCmllHZ3d9PBgwfTj/zIj+z7/dVXX50OHDgw/PzYsWMJSL/6q796o/v11re+NQHpgx/84OfcfyA973nPG75/3vOel4D0gz/4g/te913f9V3p9NNPH77/27/92wSkZzzjGfte9+QnP/l673lD+MQnPpGA9PznPz9dd9116eqrr05/8Rd/ke573/smIL3lLW8ZXvvCF74wbWxspI9+9KP73uNZz3pWMsakT33qUymllJ7+9Ken7e3t5L2/0c8t+3cyynXwiU98YvjZgx70oPSgBz1o+P6DH/xgAtJrXvOa6/39+973vpu03ynJtXTHO95x+L4cizPPPDMdP358+Pmzn/3sBKR73eteyTk3/PyJT3xiqus6LZfLlJJcH9ba9OhHP3rf51x66aUJSD/wAz+w7+fvec97rrevBXe7290SkIC0ubmZfuEXfuF61+sN4eRjVY7H7W9/+7SzszP8/M1vfnMC0q//+q+nlFLqui6dfvrp6b73ve++fXzta1+bgH3vOWLEiBEjRoy4+TFa7UaMGDFixIgvEx72sIdx5plncv755/OEJzyBzc1N3vrWt3L7299+3+t+/Md/fN/3b3/72zHG8FM/9VP7fv7MZz6TlBKXX345AH/8x39MjJHnPve5aL3/EV+sX+9617s4fvw4T3ziEzl8+PDwZYzh/ve/P+973/sAmEwm1HXN+9//fo4dO3aD+3Pw4EEA/vf//t84577g4/FjP/Zj+76/8MILOXLkCDs7OwD82Z/9GcDQFa3gaU972hf0Oc973vM488wzOeecc7jwwgv5t3/7N17+8pfz2Mc+dnjNW97yFi688EIOHTq077g87GEPI4TA//k//weQfZ7NZrzrXe/6gvf3S8WDH/xgUkpftNoJ4HGPexwHDhwYvr///e8PwPd93/ftC4C///3vT9/3XHXVVQC85z3vwXt/k8/F29/+du5xj3vss/sVvOY1r+HP/uzPuOyyy7j73e/OYrEghPBF79OTnvQktra2hu8f+9jHcrvb3Y63v/3tgNhBjxw5wo/8yI/
"text/plain": [
"<Figure size 1500x1000 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"0: 448x640 1 , 10.6ms\n",
"Speed: 2.0ms preprocess, 10.6ms inference, 1.0ms postprocess per image at shape (1, 3, 448, 640)\n"
]
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1000x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1000x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABJ4AAAIqCAYAAABlmICzAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOy9ebwtV1nm/11D1R7OOXfICAQS6AAiNhpEAdGQBDFhFgXS0kyBVoIDk8gk+GMUCbOCDNoKCmkRsINMMTKr3dKQKCoIzWDCPGS6wzln71211np/f7zvqnMvN4EwNQ718rnk3n32qV27atVa633e53leJyLCGGOMMcYYY4wxxhhjjDHGGGOMMcYYY3yHw3+vT2CMMcYYY4wxxhhjjDHGGGOMMcYYY4x/nzECT2OMMcYYY4wxxhhjjDHGGGOMMcYYY3xXYgSexhhjjDHGGGOMMcYYY4wxxhhjjDHG+K7ECDyNMcYYY4wxxhhjjDHGGGOMMcYYY4zxXYkReBpjjDHGGGOMMcYYY4wxxhhjjDHGGOO7EiPwNMYYY4wxxhhjjDHGGGOMMcYYY4wxxnclRuBpjDHGGGOMMcYYY4wxxhhjjDHGGGOM70qMwNMYY4wxxhhjjDHGGGOMMcYYY4wxxhjflRiBpzHGGGOMMcYYY4wxxhhjjDHGGGOMMb4rMQJPY4wxxhhjjPFvOJxzPP3pT/9en8a/yjj99NM5/fTTv+PHPeecc7jxjW/8HT/uGP92433vex/OOd73vvd9r09ljDHGGGOMMf7VxQg8jTHGGGOM8W86XvOa1+CcG/5Mp1NufvOb8yu/8it85Stf+V6f3r/buOyyyw677t57jjrqKO5617vyt3/7t9/r07vG+OIXv8jTn/50PvzhD3+vT+U7Ere5zW34pV/6pe/a8c8//3ycc6yvr1/jzz/2sY9xl7vchfX1dY466ige9KAHcfnllx/xvt/8zd/kXve6F8cff/w3BErf9a53ccYZZ3DMMcewZ88ebnvb2/La1772iPe94hWv4H73ux8nnngizjnOOeecaz3mJZdcwj3ucQ+ud73rsb6+zg/+4A/yO7/zO+ScD3vfjW9848PGdP3ziEc84lqPPcYYY4wxxhhjfOOI3+sTGGOMMcYYY4zvRDzzmc/kJje5Ccvlkr/5m7/hFa94Be94xzv4yEc+wnw+/16f3nctFosFMX7vlvP73//+3O1udyPnzCc+8Qle/vKXc8YZZ/ChD32IW93qVt+z87qm+OIXv8gznvEMbnzjG3PKKad8y8f5/d//fUop37kT+xbiS1/6En//93/PM5/5zO/K8Tc3N3nCE57A2traNf7885//PHe84x3ZvXs3z3nOc9jc3OQFL3gB//RP/8QHP/hB2rYd3vvUpz6V613vetz61rfmoosuutbPfMtb3sK9731vfuzHfoynP/3pOOd4wxvewIMf/GCuuOIKHvvYxw7vPe+88zh48CC3ve1t+dKXvnStx7zkkku4wx3uwM1udjOe+MQnMp/PufDCC3n0ox/Npz/9aX77t3/7sPefcsopPO5xjzvstZvf/OZf91oB3PGOd2SxWBz2vccYY4wxxhhjDI0ReBpjjDHGGOPfRdz1rnflR37kRwD4+Z//eY4++mhe9KIX8ed//ufc//73v8bf2drautbE+t9KTKfT7+nn//AP/zAPfOADh3+feuqp3PWud+UVr3gFL3/5y7+HZ/bdi6ZpvtenwIUXXsh0OuVOd7rTtb5ne3v7WwZdn/3sZ7OxscEZZ5zBm9/85iN+/pznPIetrS0uueQSTjzxRABue9vb8lM/9VO85jWv4eEPf/jw3ksvvZQb3/jGXHHFFRx77LHX+pkve9nLuP71r8973vMeJpMJAOeeey63uMUteM1rXnMY8PT+979/YDtdGyML4FWvehUAf/VXf8VRRx01HPO0007jNa95zRHA0wknnHDYeL6u4b3/nj+LY4wxxhhjjPGvNUap3RhjjDHGGP8uoybkl156KaC+POvr63z605/mbne7GxsbGzzgAQ8AFIB63OMex41udCMmkwnf933fxwte8AJE5Ijjvu51r+O2t70t8/mcvXv3csc73pG//Mu/POw9F154Iaeeeipra2tsbGxw97vfnY9+9KOHvefLX/4yD33oQ7nhDW/IZDLh+te/Pj/90z/NZZddNrzn4osv5qyzzuKYY45hNptxk5vchIc97GGHHedrpUuVKfKpT32Kc845hz179rB7924e+tCHsr29fdjvLhYLHvWoR3HMMcewsbHBve51L77whS98W75Rp556KgCf/vSnD3t93759POYxjxmu8U1velPOO++8I5hDr3/967nNbW7DxsYGu3bt4la3utVh4ED9fl8bVXJ56PU7NN73vvfxoz/6owA89KEPHWRUr3nNawAFaT7+8Y9zxRVXfMPv+LUeT1V2+IIXvIDf/d3f5T/9p//EfD7nzDPP5HOf+xwiwrOe9SxueMMbMpvN+Omf/mmuuuqqw45ZSuHpT386N7jBDZjP55xxxhn88z//Mze+8Y2vUUb29re/nTPOOIPZbAaon9V//s//mUsuuYQ73vGOzOdzfv3Xfx24dh+wazv2Jz/5SV784hfzohe96FrZdH/2Z3/GPe5xjwF0Arjzne/MzW9+c97whjcc8TnXJQ4cOMDevXsH0AkgxjiM/0PjpJNOusZxcE3HnE6n7Nmz57DXr3/96x9xzBpd17G1tXWdzrnGNXk8HXpP7nCHOwzP8Ctf+cojfv8zn/kM97rXvVhbW+O4447jsY99LBdddNHoGzXGGGOMMca/ixiBpzHGGGOMMf5dRgU+jj766OG1lBJnnXUWxx13HC94wQu4z33ug4hwr3vdixe/+MXc5S534UUvehHf933fx+Mf/3h+9Vd/9bBjPuMZz+BBD3oQTdPwzGc+k2c84xnc6EY34j3vec/wnte+9rXc/e53Z319nfPOO4/f+I3f4J//+Z/5iZ/4icNAkfvc5z5ccMEFPPShD+XlL385j3rUozh48CCf/exnAfjqV7/KmWeeyWWXXcaTnvQkXvrSl/KABzyAD3zgA9fp+5999tkcPHiQ3/qt3+Lss8/mNa95Dc94xjMOe88555zDS1/6Uu52t7tx3nnnMZvNuPvd7/5NXeevjfod9+7dO7y2vb3Naaedxute9zoe/OAH8zu/8zv8+I//OE9+8pMPu8bvfOc7uf/978/evXs577zzeO5zn8vpp5/O//pf/+vbOieA7//+7x9kaQ9/+MN57Wtfy2tf+1rueMc7AvDBD36Q7//+7+dlL3vZt/wZ559/Pi9/+ct55CMfyeMe9zje//73c/bZZ/PUpz6Vv/iLv+CJT3wiD3/4w3nrW9/Kr/3arx32u09+8pN5xjOewY/8yI/w/Oc/n5vd7GacddZZ1wiA9H3Pu971Lu52t7sd9vqVV17JXe96V0455RRe8pKXcMYZZ3xL3+Mxj3kMZ5xxxhHHr/GFL3yBr371qwPD8NC47W1vy9///d9/S597+umn89GPfpTf+I3f4FOf+hSf/vSnedaznsXFF1/ME57whG/5mAcOHODcc8/lYx/7GJ/5zGd45Stfyf/8n/+TJz/5yUe8/z3veQ/z+Zz19XVufOMbH8GI+mbj6quv5m53uxu3uc1teN7znscNb3hDfvEXf5E//MM/HN6ztbXFne50J971rnfxqEc9iqc85Sn87//9v3niE5/4bX32GGOMMcYYY/yrCRljjDHGGGOMf8Px6le/WgB517veJZdffrl87nOfk9e//vVy9NFHy2w2k89//vMiIvKQhzxEAHnSk5502O+/+c1vFkCe/exnH/b6fe97X3HOyac+9SkREfnkJz8p3nv5mZ/5Gck5H/beUoqIiBw8eFD27Nkjv/ALv3DYz7/85S/L7t27h9evvvpqAeT5z3/+tX6vCy64QAD50Ic+9HW/PyBPe9rThn8/7WlPE0Ae9rCHHfa+n/mZn5Gjjz56+Pcll1wigDzmMY857H3nnHPOEce8prj00ksFkGc84xly+eWXy5e//GX567/+a/nRH/1RAeSNb3zj8N5
"text/plain": [
"<Figure size 1500x1000 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import numpy as np\n",
"import cv2\n",
"from matplotlib import pyplot as plt\n",
"import torch\n",
"import torch.nn as nn\n",
"from torchvision import transforms\n",
"from ultralytics import YOLO\n",
"\n",
"# Configuration\n",
"DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
"\n",
"# OCR Classes\n",
"CLASSES = \"ABEKMHOPCTYX0123456789\"\n",
"\n",
"# Image Transformations\n",
"transform = transforms.Compose([\n",
" transforms.ToPILImage(),\n",
" transforms.Grayscale(),\n",
" transforms.Resize((28, 28)),\n",
" transforms.ToTensor(),\n",
" transforms.Normalize((0.25,), (0.25,))\n",
"])\n",
"\n",
"# Define the OCR Model\n",
"class ImprovedCNN(nn.Module):\n",
" def __init__(self, num_classes):\n",
" super(ImprovedCNN, self).__init__()\n",
" self.conv_layers = nn.Sequential(\n",
" nn.Conv2d(1, 32, kernel_size=3, padding=1),\n",
" nn.SiLU(),\n",
" nn.BatchNorm2d(32),\n",
" nn.MaxPool2d(kernel_size=2, stride=2),\n",
"\n",
" nn.Conv2d(32, 64, kernel_size=3, padding=1),\n",
" nn.SiLU(),\n",
" nn.BatchNorm2d(64),\n",
" nn.MaxPool2d(kernel_size=2, stride=2),\n",
"\n",
" nn.Conv2d(64, 128, kernel_size=3, padding=1),\n",
" nn.SiLU(),\n",
" nn.BatchNorm2d(128),\n",
" nn.AdaptiveAvgPool2d((1, 1))\n",
" )\n",
" self.fc_layers = nn.Sequential(\n",
" nn.Linear(128, 256),\n",
" nn.SiLU(),\n",
" nn.Linear(256, num_classes)\n",
" )\n",
"\n",
" def forward(self, x):\n",
" x = self.conv_layers(x)\n",
" x = x.view(x.size(0), -1)\n",
" x = self.fc_layers(x)\n",
" return x\n",
"\n",
"# Load the OCR Model\n",
"ocr_model = ImprovedCNN(len(CLASSES)).to(DEVICE)\n",
"SAVE_PATH = \"best_model_9.pth\"\n",
"try:\n",
" ocr_model.load_state_dict(torch.load(SAVE_PATH, map_location=DEVICE))\n",
" ocr_model.eval()\n",
"except Exception as e:\n",
" print(f\"Error loading OCR model: {e}\")\n",
"\n",
"# Load YOLO Model\n",
"yolo_model = YOLO(\"yolo_plate.pt\")\n",
"\n",
"# OCR Functions (Same as before)\n",
"def extract_symbols(image, masks):\n",
" # Function code remains the same\n",
" img_h, img_w = image.shape\n",
" symbols = []\n",
" for bbox in masks:\n",
" x_frac, y_frac, w_frac, h_frac = bbox\n",
" x = int(x_frac * img_w)\n",
" y = int(y_frac * img_h)\n",
" w = int(w_frac * img_w)\n",
" h = int(h_frac * img_h)\n",
" x_end = min(x + w, img_w)\n",
" y_end = min(y + h, img_h)\n",
" symbol = image[y:y_end, x:x_end]\n",
" if symbol.size == 0:\n",
" continue\n",
" symbols.append(symbol)\n",
" return symbols\n",
"\n",
"def is_symbol_present(symbol, threshold=250):\n",
" return np.mean(symbol) < threshold\n",
"\n",
"# Masks and Expected Types (Same as before)\n",
"expected_types_8 = ['letter', 'digit', 'digit', 'digit', 'letter', 'letter', 'digit', 'digit']\n",
"expected_types_9 = ['letter', 'digit', 'digit', 'digit', 'letter', 'letter', 'digit', 'digit', 'digit']\n",
"\n",
"mask_8 = [\n",
" (0.03, 0.05, 0.12, 0.9),\n",
" (0.16, 0.05, 0.12, 0.9),\n",
" (0.28, 0.05, 0.12, 0.9),\n",
" (0.40, 0.05, 0.12, 0.9),\n",
" (0.52, 0.05, 0.12, 0.9),\n",
" (0.64, 0.05, 0.12, 0.9),\n",
" (0.79, 0.07, 0.10, 0.60),\n",
" (0.89, 0.07, 0.10, 0.60),\n",
"]\n",
"\n",
"mask_9 = [\n",
" (0.05, 0.2, 0.1, 0.6),\n",
" (0.17, 0.2, 0.1, 0.6),\n",
" (0.29, 0.2, 0.1, 0.6),\n",
" (0.41, 0.2, 0.1, 0.6),\n",
" (0.53, 0.2, 0.1, 0.6),\n",
" (0.65, 0.2, 0.1, 0.6),\n",
" (0.77, 0.2, 0.1, 0.6),\n",
" (0.89, 0.2, 0.1, 0.6),\n",
" (1.01, 0.2, 0.1, 0.6)\n",
"]\n",
"\n",
"digits = set(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'])\n",
"letters = set([c for c in CLASSES if c.isalpha()])\n",
"\n",
"def process_plate(plate):\n",
" # Function code remains the same\n",
" gray_plate = cv2.cvtColor(plate, cv2.COLOR_BGR2GRAY)\n",
" resized_plate = cv2.resize(gray_plate, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)\n",
" blurred = cv2.GaussianBlur(resized_plate, (3, 3), 0)\n",
" symbols_8 = extract_symbols(blurred, mask_8)\n",
" symbols_9 = extract_symbols(blurred, mask_9)\n",
" if len(symbols_9) == 9 and is_symbol_present(symbols_9[-1]):\n",
" characters = symbols_9\n",
" expected_types = expected_types_9\n",
" else:\n",
" characters = symbols_8\n",
" expected_types = expected_types_8\n",
" return blurred, characters, expected_types\n",
"\n",
"def recognize_plate(plate_image):\n",
" # Function code remains the same\n",
" if plate_image is None:\n",
" return None\n",
" processed_plate, characters, expected_types = process_plate(plate_image)\n",
" predictions = []\n",
" for idx, (symbol_img, expected_type) in enumerate(zip(characters, expected_types)):\n",
" input_tensor = transform(symbol_img).unsqueeze(0).to(DEVICE)\n",
" with torch.no_grad():\n",
" outputs = ocr_model(input_tensor)\n",
" probabilities = torch.nn.functional.softmax(outputs, dim=1)\n",
" indices = torch.argmax(probabilities, dim=1)\n",
" predicted_label = CLASSES[indices[0]]\n",
" if expected_type == 'letter':\n",
" if predicted_label == '0':\n",
" predicted_label = 'O'\n",
" elif predicted_label == '8':\n",
" predicted_label = 'B'\n",
" if predicted_label not in letters:\n",
" continue\n",
" elif expected_type == 'digit':\n",
" if predicted_label == 'O':\n",
" predicted_label = '0'\n",
" elif predicted_label == 'B':\n",
" predicted_label = '8'\n",
" if predicted_label not in digits:\n",
" continue\n",
" predictions.append(predicted_label)\n",
" plate_number = ''.join(predictions)\n",
" return plate_number\n",
"\n",
"# Perspective Transformation Functions\n",
"def order_points(pts):\n",
" rect = np.zeros((4, 2), dtype=\"float32\")\n",
" pts = np.array(pts)\n",
" s = pts.sum(axis=1)\n",
" rect[0] = pts[np.argmin(s)] # Top-left\n",
" rect[2] = pts[np.argmax(s)] # Bottom-right\n",
" diff = np.diff(pts, axis=1)\n",
" rect[1] = pts[np.argmin(diff)] # Top-right\n",
" rect[3] = pts[np.argmax(diff)] # Bottom-left\n",
" return rect\n",
"\n",
"def four_point_transform(image, pts):\n",
" rect = order_points(pts)\n",
" (tl, tr, br, bl) = rect\n",
" widthA = np.hypot(br[0] - bl[0], br[1] - bl[1])\n",
" widthB = np.hypot(tr[0] - tl[0], tr[1] - tl[1])\n",
" maxWidth = max(int(widthA), int(widthB))\n",
" heightA = np.hypot(tr[0] - br[0], tr[1] - br[1])\n",
" heightB = np.hypot(tl[0] - bl[0], tl[1] - bl[1])\n",
" maxHeight = max(int(heightA), int(heightB))\n",
" dst = np.array([\n",
" [0, 0],\n",
" [maxWidth - 1, 0],\n",
" [maxWidth - 1, maxHeight - 1],\n",
" [0, maxHeight - 1]], dtype=\"float32\")\n",
" M = cv2.getPerspectiveTransform(rect, dst)\n",
" warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))\n",
" return warped\n",
"\n",
"# Debug Function\n",
"def show_debug_image(title, image):\n",
" plt.figure(figsize=(10, 6))\n",
" if len(image.shape) == 2: # grayscale\n",
" plt.imshow(image, cmap='gray')\n",
" else:\n",
" plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))\n",
" plt.title(title)\n",
" plt.axis('off')\n",
" plt.show()\n",
"\n",
"# Main Processing Function\n",
"def process_and_display_plate(image_path, padding=20):\n",
" image = cv2.imread(image_path)\n",
" if image is None:\n",
" print(f\"Failed to load image at path: {image_path}\")\n",
" return\n",
" output_image = image.copy()\n",
"\n",
" # YOLO Detection\n",
" results = yolo_model.predict(image)\n",
" plate_found = False\n",
" best_confidence = -1\n",
" best_plate_image = None\n",
" best_plate_box = None\n",
"\n",
" for result in results:\n",
" boxes = result.boxes\n",
" if boxes is None or len(boxes) == 0:\n",
" continue\n",
" for box in boxes:\n",
" confidence = box.conf.item()\n",
" if confidence > best_confidence:\n",
" best_confidence = confidence\n",
" x1, y1, x2, y2 = map(int, box.xyxy[0].tolist())\n",
" x1_padded = max(x1 - padding, 0)\n",
" y1_padded = max(y1 - padding, 0)\n",
" x2_padded = min(x2 + padding, image.shape[1])\n",
" y2_padded = min(y2 + padding, image.shape[0])\n",
" plate_crop = image[y1_padded:y2_padded, x1_padded:x2_padded]\n",
" best_plate_image = plate_crop\n",
" best_plate_box = np.array([[x1_padded, y1_padded], [x2_padded, y1_padded],\n",
" [x2_padded, y2_padded], [x1_padded, y2_padded]], dtype=\"float32\")\n",
" plate_found = True\n",
"\n",
" if plate_found:\n",
" # Show the detected plate\n",
" cv2.polylines(output_image, [np.int0(best_plate_box)], isClosed=True, color=(0, 255, 0), thickness=2)\n",
" show_debug_image(\"Detected Plate\", best_plate_image)\n",
"\n",
" # If the plate is tilted, use minAreaRect to get the correct bounding box\n",
" gray = cv2.cvtColor(best_plate_image, cv2.COLOR_BGR2GRAY)\n",
" _, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)\n",
" contours, _ = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)\n",
"\n",
" if contours:\n",
" largest_contour = max(contours, key=cv2.contourArea)\n",
" rect = cv2.minAreaRect(largest_contour)\n",
" box = cv2.boxPoints(rect)\n",
" box = np.int0(box)\n",
"\n",
" # Adjust box coordinates relative to the original image\n",
" box[:, 0] += int(best_plate_box[0][0])\n",
" box[:, 1] += int(best_plate_box[0][1])\n",
"\n",
" # Apply perspective transform\n",
" plate_image = four_point_transform(image, box)\n",
"\n",
" # Show the transformed plate\n",
" show_debug_image(\"Transformed Plate\", plate_image)\n",
"\n",
" # Recognize the plate\n",
" plate_number = recognize_plate(plate_image)\n",
"\n",
" # Draw the box on the output image\n",
" cv2.polylines(output_image, [box], isClosed=True, color=(0, 0, 255), thickness=2)\n",
" else:\n",
" print(\"No contours found in the plate area.\")\n",
" plate_number = None\n",
" plate_image = None\n",
" else:\n",
" print(\"No plates detected by YOLO.\")\n",
" plate_number = None\n",
" plate_image = None\n",
"\n",
" # Display the results\n",
" height, width = image.shape[:2]\n",
" black_space_width = width // 2\n",
" black_space = np.zeros((height, black_space_width, 3), dtype=np.uint8)\n",
" if plate_found and plate_image is not None:\n",
" plate_height, plate_width = plate_image.shape[:2]\n",
" scale_factor = min(black_space_width / (plate_width + 200), height / plate_height)\n",
" new_plate_width = int(plate_width * scale_factor)\n",
" new_plate_height = int(plate_height * scale_factor)\n",
" resized_plate = cv2.resize(plate_image, (new_plate_width, new_plate_height), interpolation=cv2.INTER_AREA)\n",
" y_offset = (height - new_plate_height) // 2\n",
" black_space[y_offset:y_offset + new_plate_height, 0:new_plate_width] = resized_plate\n",
" # Display recognized plate number\n",
" if plate_number:\n",
" placeholder_text = \"Number plate:\"\n",
" decoded_text = plate_number\n",
" else:\n",
" placeholder_text = \"Not found\"\n",
" decoded_text = \"\"\n",
" font = cv2.FONT_HERSHEY_SIMPLEX\n",
" font_scale = 1\n",
" font_color = (255, 255, 255)\n",
" thickness = 2\n",
" line_type = cv2.LINE_AA\n",
" cv2.putText(black_space, placeholder_text, (new_plate_width + 20, y_offset + new_plate_height // 2),\n",
" font, font_scale, font_color, thickness, line_type)\n",
" cv2.putText(black_space, decoded_text, (new_plate_width + 20, y_offset + new_plate_height // 2 + 50),\n",
" font, font_scale, font_color, thickness, line_type)\n",
" else:\n",
" placeholder_text = \"Not found\"\n",
" font = cv2.FONT_HERSHEY_SIMPLEX\n",
" font_scale = 1\n",
" font_color = (0, 0, 255)\n",
" thickness = 2\n",
" line_type = cv2.LINE_AA\n",
" text_size, _ = cv2.getTextSize(placeholder_text, font, font_scale, thickness)\n",
" text_x = (black_space_width - text_size[0]) // 2\n",
" text_y = height // 2\n",
" cv2.putText(black_space, placeholder_text, (text_x, text_y),\n",
" font, font_scale, font_color, thickness, line_type)\n",
" combined_image = np.hstack((output_image, black_space))\n",
" combined_image_rgb = cv2.cvtColor(combined_image, cv2.COLOR_BGR2RGB)\n",
" plt.figure(figsize=(15, 10))\n",
" plt.imshow(combined_image_rgb)\n",
" plt.axis('off')\n",
" plt.title(f'Processing Result: {image_path}')\n",
" plt.show()\n",
"\n",
"# Process Images\n",
"images = ['img/1.jpg', 'img/2.jpg', 'img/3.jpg', 'img/ru4018185.jpg']\n",
"\n",
"for img_path in images:\n",
" process_and_display_plate(img_path, padding=20)\n"
]
2024-11-29 02:35:02 +01:00
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"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.9.13"
}
},
"nbformat": 4,
"nbformat_minor": 2
}