widzenie-komputerowe-MP/wko-04.ipynb

655 lines
3.0 MiB
Plaintext
Raw Permalink Normal View History

2023-01-04 14:09:18 +01:00
{
"cells": [
{
"cell_type": "markdown",
"id": "d7796c8b",
"metadata": {},
"source": [
"![Logo 1](img/aitech-logotyp-1.jpg)\n",
"<div class=\"alert alert-block alert-info\">\n",
"<h1> Widzenie komputerowe </h1>\n",
"<h2> 04. <i>Zaawansowane przetwarzanie obrazów i fotografia obliczeniowa</i> [laboratoria]</h2> \n",
"<h3>Andrzej Wójtowicz (2021)</h3>\n",
"</div>\n",
"\n",
"![Logo 2](img/aitech-logotyp-2.jpg)"
]
},
{
"cell_type": "markdown",
"id": "1454f22a",
"metadata": {},
"source": [
"W poniższych materiałach krótko omówimy zagadnienia związane z fotografią obliczeniową, a większą część czasu pozostawimy na realizację zadania dotyczącego wykrywania linii.\n",
"\n",
"Na początku załadujmy niezbędne biblioteki."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "245f995f",
"metadata": {},
"outputs": [],
"source": [
"import cv2 as cv\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"%matplotlib inline"
]
},
{
"cell_type": "markdown",
"id": "58f244a1",
"metadata": {},
"source": [
"# Obrazy HDR\n",
"\n",
"Na poprzednich zajęciach widzieliśmy w jaki sposób można poprawić kontrast np. przy pomocy wyrównania histogramu. W niektórych przypadkach jest to wystarczająca operacja pozwalająca uzyskać zadowalający efekt. Niestety, jest też wiele przypadków gdy na potrzebę uchwycenia głównych elementów na zdjęciu obraz musi mieć mniejszą lub większą ekspozycję, co kończy się niedoświetleniem lub prześwietleniem obiektów znajdujących się np. na drugim planie. Zasadniczo w takiej sytuacji chcielibyśmy wyjść poza standardowy ograniczony zakres wartości 0-255 do jakiegoś szerszego zakresu, który z jednej strony pozwoliłby nam uchwycić więcej informacji znajdujących się na scenie, ale z drugiej strony musimy też pamiętać o ponownej konwersji do standardowego zakresu.\n",
"\n",
"Pokażemy tutaj w jaki sposób można wykorzystać technikę [*High dynamic range (HDR) imaging*](https://en.wikipedia.org/wiki/High-dynamic-range_imaging) w OpenCV do uzyskania obrazu o dużej rozpiętości tonalnej. Poniżej mamy kilka zdjęć tego samego obiektu (źródło: Wikipedia, [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/deed.en)), wykonanych z różnym czasem naświetlania, przez co możemy zauważyć, że część elementów jest niedoświetlona, a część prześwietlona:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "01f5a664",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1440x360 with 4 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"exposure_times = np.array([ 1/30.0, 0.25, 2.5, 15.0 ], dtype=np.float32)\n",
" \n",
"f_names = [\"st-louis-arch-0.033.jpg\", \n",
" \"st-louis-arch-0.25.jpg\", \n",
" \"st-louis-arch-2.5.jpg\", \n",
" \"st-louis-arch-15.jpg\"]\n",
"\n",
"plt.figure(figsize=(20,5))\n",
"images = []\n",
"for i, f_name in enumerate(f_names):\n",
" image = cv.imread(f\"img/{f_name}\", cv.IMREAD_COLOR)\n",
" images.append(image)\n",
" \n",
" plt.subplot(141 + i)\n",
" plt.imshow(image[:,:,::-1])\n",
" plt.title(f\"{str(round(exposure_times[i], 3))} sec.\")"
]
},
{
"cell_type": "markdown",
"id": "9cb65411",
"metadata": {},
"source": [
"Szczegółowy opis dalszych kroków można znaleźć np. w rozdziale *10.1 Photometric calibration* i *10.2 High dynamic range imaging* książki R. Szeliski *Computer Vision* (2021) - tutaj ograniczymy się do technicznego rozwiązania kolejnych problemów.\n",
"\n",
"Pierwszym problemem, który musimy rozwiązać, jest wyrównanie/dopasowanie obrazów. Nawet jeśli zdjęcie jest robione ze statywu (lub gorzej - z ręki), to po nałożeniu zdjęć na siebie będą widoczne artefakty wynikające z wibracji i przesunięć. W OpenCV możemy to rozwiązać poprzez funkcję [`cv.createAlignMTB()`](https://docs.opencv.org/4.5.3/d7/db6/classcv_1_1AlignMTB.html), która tworzy tzw. bitmapy z progiem mediany (ang. *median threshold bitmaps*), w których zawartość obrazu jest obliczana przez przypisanie wartości 1 pikselom jaśniejszym niż mediana luminancji i 0 w przeciwnym wypadku."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "7dda882f",
"metadata": {},
"outputs": [],
"source": [
"align_mtb = cv.createAlignMTB()\n",
"align_mtb.process(images, images)"
]
},
{
"cell_type": "markdown",
"id": "8873862f",
"metadata": {},
"source": [
"W dalszych krokach musimy:\n",
"\n",
"* oszacować radiometryczną funkcję odpowiedzi na podstawie wyrównanych obrazów,\n",
"* oszacować mapę radiacyjną, wybierając lub mieszając piksele z różnych ekspozycji,\n",
"* wykonać mapowanie tonalne wynikowego obrazu HDR z powrotem do postaci umożliwiającej jego normalne wyświetlanie."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "bd00b46f",
"metadata": {},
"outputs": [],
"source": [
"calibrate_debevec = cv.createCalibrateDebevec()\n",
"response_debevec = calibrate_debevec.process(images, exposure_times)\n",
"merge_debevec = cv.createMergeDebevec()\n",
"hdr_debevec = merge_debevec.process(images, exposure_times, response_debevec)"
]
},
{
"cell_type": "markdown",
"id": "d6c1f8f3",
"metadata": {},
"source": [
"Teoretycznie moglibyśmy zapisać teraz wynikowy plik `.hdr` np. przy pomocy `cv.imwrite(\"hdr_debevec.hdr\", hdr_debevec)` i edytować dalej go w programie graficznym. W tym miejscu jednak wykonamy dalszą obróbkę przy pomocy OpenCV, tj. wykonamy mapowanie tonalne. Poniżej mamy zaprezentowane wyniki uzyskane metodą Reinharda i Mantiuka:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "4a16094f",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"[ WARN:0@261.938] global /io/opencv/modules/core/src/matrix_expressions.cpp (1333) assign OpenCV/MatExpr: processing of multi-channel arrays might be changed in the future: https://github.com/opencv/opencv/issues/16739\n"
]
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"tonemap_rReinhard = cv.createTonemapReinhard(1.5, 0,0,0)\n",
"ldr_reinhard = tonemap_rReinhard.process(hdr_debevec)\n",
"plt.imshow(ldr_reinhard[:,:,::-1]);"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "92cdbefa",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"tonemap_mantiuk = cv.createTonemapMantiuk(2.2, 0.85, 1.2)\n",
"ldr_mantiuk = tonemap_mantiuk.process(hdr_debevec)\n",
"ldr_mantiuk = np.clip(3 * ldr_mantiuk, 0, 1)\n",
"plt.imshow(ldr_mantiuk[:,:,::-1]);"
]
},
{
"cell_type": "markdown",
"id": "c4d83478",
"metadata": {},
"source": [
"# Gładkie klonowanie\n",
"\n",
"Na wcześniejszych zajęciach widzieliśmy, że możemy umieszczać elementy jednego obrazu w drugim obrazie np. poprzez wykorzystanie maski i kanału dotyczącego przezroczystości. Innym ciekawym podejściem jest praca na gradientach obrazu (zamiast na jego intensywności), co może dać równie interesujące, a czasem i bardziej realistyczne wyniki. W tzw. gładkim klonowaniu (ang. *seamless cloning*) intensywność obiektu docelowego będzie różna od intensywności obiektu źródłowego, natomiast gradienty będą podobne. Szczegóły omawianej metody znajdują się w artykule P. Perez et al. (2003) [*Poisson Image Editing*](https://www.irisa.fr/vista/Papers/2003_siggraph_perez.pdf).\n",
"\n",
"Poniżej mamy obraz basenu i kąpiących się w nim ludzi oraz niedźwiedzia, którego chcemy umieścić w basenie:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "e0d74bf3",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1440x360 with 3 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"swimmingpool = cv.imread(\"img/swimmingpool.jpg\", cv.IMREAD_COLOR)\n",
"bear = cv.imread(\"img/bear.jpg\", cv.IMREAD_COLOR)\n",
"bear_mask = cv.imread(\"img/bear-mask.jpg\", cv.IMREAD_GRAYSCALE)\n",
"\n",
"plt.figure(figsize=(20,5))\n",
"plt.subplot(131)\n",
"plt.imshow(swimmingpool[:,:,::-1])\n",
"plt.title(\"Swimming pool\")\n",
"plt.subplot(132)\n",
"plt.imshow(bear[:,:,::-1])\n",
"plt.title(\"Bear\")\n",
"plt.subplot(133)\n",
"plt.imshow(bear_mask[:,:], cmap='gray')\n",
"plt.title(\"Bear mask\");"
]
},
{
"cell_type": "markdown",
"id": "7654ece6",
"metadata": {},
"source": [
"Przy pomocy metody [`cv.seamlessClone()`](https://docs.opencv.org/4.5.3/df/da0/group__photo__clone.html#ga2bf426e4c93a6b1f21705513dfeca49d) wykonujemy gładkie klonowanie:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "f6d3092b",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 720x720 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"center = (250,700)\n",
"\n",
"swimmingpool_with_bear = cv.seamlessClone(bear, swimmingpool, bear_mask, center, cv.NORMAL_CLONE)\n",
"\n",
"plt.figure(figsize=(10,10))\n",
"plt.imshow(swimmingpool_with_bear[:,:,::-1])\n",
"plt.title(\"I think this might be photoshopped\");"
]
},
{
"cell_type": "markdown",
"id": "2337a4c3",
"metadata": {},
"source": [
"Spróbujmy teraz umieścić tekst na teksturze:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "f61aaaaf",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1440x360 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"texture = cv.imread(\"img/texture.jpg\", cv.IMREAD_COLOR)\n",
"bologna = cv.imread(\"img/bologna-on-wall.jpg\", cv.IMREAD_COLOR)\n",
"\n",
"plt.figure(figsize=(20,5))\n",
"plt.subplot(131)\n",
"plt.imshow(texture[:,:,::-1])\n",
"plt.title(\"Texture\")\n",
"plt.subplot(132)\n",
"plt.imshow(bologna[:,:,::-1])\n",
"plt.title(\"Bologna to clone\");"
]
},
{
"cell_type": "markdown",
"id": "99a99732",
"metadata": {},
"source": [
"W tym wypadku stworzenie maski może być problematyczne, zatem możemy pójść na skróty i przyjąć, że cały obraz stanowi maskę. Przy takim podejściu zobaczymy jednak, że opcja [`cv.NORMAL_CLONE`](https://docs.opencv.org/4.5.3/df/da0/group__photo__clone.html#gabfc4ba1d1fb873f2b56d34032f86c1d4) spowoduje mocne rozmazanie wokół wklejanej części, stąd też lepszym rozwiązaniem będzie opcja `cv.MIXED_CLONE`, co wynika z kombinacji gradientów z jednego i drugiego obrazu:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "a64d730e",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1440x720 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"mask = 255 * np.ones(bologna.shape, bologna.dtype)\n",
"\n",
"width, height, channels = texture.shape\n",
"center = (height//2, width//2)\n",
"\n",
"normal_clone = cv.seamlessClone(bologna, texture, mask, center, cv.NORMAL_CLONE)\n",
"mixed_clone = cv.seamlessClone(bologna, texture, mask, center, cv.MIXED_CLONE)\n",
"\n",
"plt.figure(figsize=[20,10])\n",
"plt.subplot(121)\n",
"plt.title(\"Normal clone\")\n",
"plt.imshow(normal_clone[:,:,::-1])\n",
"plt.subplot(122)\n",
"plt.title(\"Mixed clone\")\n",
"plt.imshow(mixed_clone[:,:,::-1])\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "b3df663d",
"metadata": {},
"source": [
"# Usuwanie niechcianych obiektów\n",
"\n",
"Spróbujemy teraz usunąć ze zdjęcia defekty, które często są domeną starych fotografii. Poniżej mamy zdjęcie prezydenta Lincolna z rysą na poziomie włosów; dodatkowo ręcznie ustaliliśmy maskę wskazującą miejsce występowania tej rysy:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "35d05105",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1080x720 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"lincoln = cv.imread(\"img/lincoln.jpg\", cv.IMREAD_COLOR)\n",
"lincoln_mask = cv.imread(\"img/lincoln-mask.jpg\", cv.IMREAD_GRAYSCALE)\n",
"\n",
"plt.figure(figsize=(15,10))\n",
"plt.subplot(121)\n",
"plt.imshow(lincoln[:,:,::-1])\n",
"plt.title(\"Lincoln last photo\")\n",
"plt.subplot(122)\n",
"plt.imshow(lincoln_mask[:,:], cmap='gray')\n",
"plt.title(\"Mask\");"
]
},
{
"cell_type": "markdown",
"id": "ba912b4f",
"metadata": {},
"source": [
"Używając metody [`cv.inpaint()`](https://docs.opencv.org/4.5.3/d7/d8b/group__photo__inpaint.html#gaedd30dfa0214fec4c88138b51d678085) możemy przywrócić wybrany region w obrazie przy pomocy sąsiedztwa zadanego regionu. Metoda `cv.INPAINT_NS` implementuje podejście opisane w M. Bertalmio et al. (2001) [*Navier-Stokes, Fluid Dynamics, and Image and Video Inpainting*](https://www.math.ucla.edu/~bertozzi/papers/cvpr01.pdf), która ogólnie mówiąc ma za zadanie zachować gradienty (np. krawędzie) i rozprowadzać informacje o kolorach na płaskich przestrzeniach. Z kolei `cv.INPAINT_TELEA` implementuje metodę opisaną w A. Telea (2004) [*An image inpainting technique based on the fast marching method*](https://core.ac.uk/download/pdf/148284148.pdf). W obu przypadkach możemy zauważyć oczekiwane wypełnienie na poziomie włosów, aczkolwiek po prawej stronie jest widoczne pewne rozmazanie - być może należałoby poprawić/zawęzić wejściową maskę."
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "52ff1513",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1080x720 with 3 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"lincoln_inpainted_ns = cv.inpaint(src=lincoln, inpaintMask=lincoln_mask, inpaintRadius=5, flags=cv.INPAINT_NS)\n",
"lincoln_inpainted_t = cv.inpaint(src=lincoln, inpaintMask=lincoln_mask, inpaintRadius=5, flags=cv.INPAINT_TELEA)\n",
"\n",
"plt.figure(figsize=(15,10))\n",
"plt.subplot(131)\n",
"plt.imshow(lincoln[:,:,::-1])\n",
"plt.title(\"Lincoln last photo\")\n",
"plt.subplot(132)\n",
"plt.imshow(lincoln_inpainted_ns[:,:,::-1])\n",
"plt.title(\"Inpainted: Navier-Stokes\")\n",
"plt.subplot(133)\n",
"plt.imshow(lincoln_inpainted_t[:,:,::-1])\n",
"plt.title(\"Inpainted: Telea\");"
]
},
{
"cell_type": "markdown",
"id": "62854178",
"metadata": {},
"source": [
"# Transformata Hougha"
]
},
{
"cell_type": "markdown",
"id": "6cc98b55",
"metadata": {},
"source": [
"## Zadanie 1\n",
"\n",
"W poniższym zadaniu należy przygotować serię operacji, która pozwoli wykryć proste linie na obrazie `img/road-lanes.jpg` przy pomocy [transformaty Hougha](https://docs.opencv.org/4.5.3/d9/db0/tutorial_hough_lines.html) (wym. *hafa*), zaimplementowanej w funkcji [`cv.HoughLines()`](https://docs.opencv.org/4.5.3/dd/d1a/group__imgproc__feature.html#ga46b4e588934f6c8dfd509cc6e0e4545a) lub [`cv.HoughLinesP()`](https://docs.opencv.org/4.5.3/dd/d1a/group__imgproc__feature.html#ga8618180a5948286384e3b7ca02f6feeb). Możemy przyjąć, że przetwarzane zdjęcie jest pojedynczą klatką uzyskaną w kamery znajdującej się na jadącym samochodzie.\n",
"\n",
"Kolejne kroki mogą wyglądać następująco:\n",
"\n",
"1. progowanie obrazu w celu uzyskania pasów na drodze,\n",
"2. ograniczenie przetwarzanego obrazu do interesującego nas fragmentu (np. może to być traprez osadzony na dole ekranu zwężający się do środka - góra i boki nas za bardzo nie interesują),\n",
"3. wykrycie krawędzi,\n",
"4. wykrycie linii transformatą Hougha,\n",
"5. ekstrapolacja znalezionych wyżej linii,\n",
"6. naniesienie linii na obraz wejściowy."
]
},
{
"cell_type": "code",
"execution_count": 126,
"id": "ee2d2368",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x7f897e801250>"
]
},
"execution_count": 126,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAlYAAAC+CAYAAAD3LUHZAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAAsTAAALEwEAmpwYAAAkq0lEQVR4nO3deZQU9bn/8ffTPQvLDArMiAgICoILN5KBuORyBQKJKDFAQCI/bzAuYFDjdWW5uWpA44I5iojbKEbidYEEuS4nEXGCMeacqOCCDoKAgQgKAiISBFnm+f3RNWYgjLNVd/XyeZ3zHKqra7qf6m6eeeZb36o2d0dEREREmi4WdQIiIiIi2UKNlYiIiEhI1FiJiIiIhESNlYiIiEhI1FiJiIiIhESNlYiIiEhI1FhJUpjZT8zslajzEBGJkpn1N7N1UechqaPGSkRERCQkaqxEREREQqLGSprMzDqZ2VNmtsnMtpjZzINsc6yZLTSzT81shZmNqnHfEDN708w+N7MPzewXNe7rYmZuZueZ2d/NbLOZ/TxFuyYiWc7M1pjZtWa21Mx2mNksM2tnZn8ws+1m9qKZtQ62/a2ZbTCzbWb2spmdUONxzjSzZcHPrDeza2p5vsuD7Tqmah8ltdRYSZOYWRx4DlgLdAE6AE8esE1LYCHwOHAYcA5wr5kdH2yyAxgDHAoMAcab2bADnqov0AMYCFxvZseFvzcikqNGAN8FugNnAX8A/hsoJfF78vJguz8Ax5CoY28Aj9V4jFnAxe5eDPQE/njgk5jZ9cBPgH7urnlXWUqNlTTVScARwLXuvsPdd7n7gZPWvw+scfdfu/ted38TmAecDeDuL7n7O+5e5e5LgSeAfgc8xhR33+nubwNvAycmda9EJJfc7e4b3X098GfgVXd/0913AfOBbwK4+8Puvt3dvwR+AZxoZocEj7EHON7MWrn7Vnd/o8bjm5ndAXwPGODum1K1Y5J6aqykqToBa91979ds0xk42cw+qw7gXOBwADM72cwWBYcStwE/BUoOeIwNNZa/AIpC2wMRyXUbayzvPMjtIjOLm9mtZrbazD4H1gT3V9eqEcCZwFoz+5OZnVrjMQ4FxgG3uPu2ZOyApA81VtJUHwJHmlleHdv8yd0PrRFF7j4+uP9x4Bmgk7sfAtwPWHLTFhFpkP8HDAUGAYeQmPoAQa1y99fdfSiJw4T/B8yt8bNbSYzc/9rM/j1F+UpE1FhJU70GfAzcamYtzazZQQrHc0B3M/uxmeUH8a0a86SKgU/dfZeZnUSigImIpJNi4EtgC9ACuLn6DjMrMLNzzewQd98DfA5U1fxhd3+JxEj9U0GdkyylxkqaxN33kZjs2Q34O7AO+NEB22wnMbfgHOAjEof1bgMKg00uAaaa2Xbgevb/S09EJB38hsRJOuuBZcBfD7j/x8Ca4DDhT0k0Uftx94XABcCzZlaW3HQlKubuUecgIiIikhU0YiUiIiISkqQ0VmY2OLgI5Cozm5SM5xARSRbVMBFprNAPBQYXjHyfxMXW1gGvA6PdfVmoTyQikgSqYSLSFMkYsToJWOXuH7j7bhJX4R6ahOcREUkG1TARabRkNFYdSFy3qNq6YJ2ISCZQDRORRvu6izomlZmNI3ElWoDeUeUhIpHZ7O6lUSfRGKpfIjmv1vqVjMZqPYmvOanWMVi3H3cvB8oBzEzXfBDJPWujTqAWddYw1S+RnFdr/UrGocDXgWPM7CgzKyBxUchnkvA8IiLJoBomIo0W+oiVu+81s8uABUAceNjdK8N+HhGRZFANE5GmSIsrr2soXSQnLXH3PlEn0VSqXyI5qdb6pSuvi4iIiIREjZWIiIhISNRYiYiIiIREjZWIiIhISNRYiYiIiIREjZWIiIhISNRYiYiIiIREjZWIiIhISNRYiYiIiIREjZWIiIhISNRYiYiIiIREjZWIiIhISNRYiYiIiIREjZWIiIhISNRYiYiIiIREjZWIiIhISNRYiYiIiIREjZWIiIhISOpsrMzsYTP7xMzerbGujZktNLOVwb+tg/VmZjPMbJWZLTWzsmQmLyJSF9UwEUml+oxYPQIMPmDdJKDC3Y8BKoLbAGcAxwQxDrgvnDRFRBrtEVTDRCRF6mys3P1l4NMDVg8FZgfLs4FhNdb/xhP+ChxqZu1DylVEpMFUw0QklRo7x6qdu38cLG8A2gXLHYAPa2y3LlgnIpJOVMNEJCnymvoA7u5m5g39OTMbR2KoXUQkMo2pYapfIlKbxo5YbaweHg/+/SRYvx7oVGO7jsG6f+Hu5e7ex937NDIHEZHGalINU/0Skdo0trF6BjgvWD4PeLrG+jHBmTWnANtqDLeLiKQL1TARSYo6DwWa2RNAf6DEzNYBNwC3AnPN7EJgLTAq2Pz3wJnAKuAL4Pwk5CwiUm+qYSKSSube4OlR4SfRiDlaIpLxlmTDoTTVL5GcVGv90pXXRUREREKixkpEREQkJGqsREREREKixkpEREQkJGqsREREREKixkpEREQkJGqsREREREKixkpEREQkJGqsREREREKixkpEREQkJGqsREREREKixkpEREQkJGqsREREREKixkpEREQkJGqsREREREKixkpEREQkJGqsREREREJSZ2NlZp3MbJGZLTOzSjP7r2B9GzNbaGYrg39bB+vNzGaY2SozW2pmZcneCRGRg1H9EpFUq8+I1V7ganc/HjgFuNTMjgcmARXufgxQEdwGOAM4JohxwH2hZy0iUj+qXyKSUnU2Vu7+sbu/ESxvB94DOgBDgdnBZrOBYcHyUOA3nvBX4FAzax924iIidVH9EpFUa9AcKzPrAnwTeBVo5+4fB3dtANoFyx2AD2v82LpgnYhIZFS/RCQV8uq7oZkVAfOAK9z9czP76j53dzPzhjyxmY0jMdQuIpJUql8ikir1GrEys3wSRekxd38qWL2xeog8+PeTYP16oFONH+8YrNuPu5e7ex9379PY5EVE6qL6JSKpVJ+zAg2YBbzn7nfUuOsZ4Lxg+Tzg6RrrxwRn15wCbKsx5C4ikjKqXyKSaub+9SPgZtYX+DPwDlAVrP5vEvMU5gJHAmuBUe7+aVDIZgKDgS+A8919cR3P0aBheBHJCkuSPeKj+iUiSVJr/aqzsUoFFSaRnJT0xioVVL9EclKt9UtXXhcREREJiRorERERkZCosRIREREJiRorERERkZCosRIREREJiRorERERkZCosRIREREJSb2/K1BERCRT5eXp1x3Avn37SIfrV2YzfdJERCRrmRn/+Z//yfjx46n55du56pFHHqG8vFzNVRKpsRIRkaxkZowZM4aZM2dSVFQUdTppoWvXrixfvpw//elPUaeStTTHSkREso6aqoMrLS3lgQce4Mgjj4w6laylxkpERLKKmfHjH/+Yu+++W03VQfTo0YP//d//paSkJOpUspIaKxERySpDhgxh5syZFBcXR51K2urbty9Tp06lefPmUaeSddRYiYhI1igrK2P69OlqqupgZowbN44LLriAWEytQJj0aoqISFYoKytj7ty5dO3aNepUMkI8HufWW29l0KBBUaeSVdRYiYhIxisrK2POnDlqqhqoqKiI+++/nxNOOCHqVLKGGisREclo1U1Vt27dok4lIx111FFMnz6ddu3aRZ1KVlBjJSIiGUtNVTgGDRrEHXfcQWFhYdSpZLw6Gysza2Zmr5nZ22ZWaWZTgvVHmdmrZrbKzOaYWUGwvjC4vSq4v0t9EmnRokWTdkRE5ECpql8SDTVV4Ro1ahSTJk3SFeqbqD4jVl8C33H3E4FewGAzOwW4DbjT3bsBW4ELg+0vBLYG6+8MtvtaZsb48ePJz89vxC6IiNQq6fVLoqGmKnx5eXlcddVVjBw5MupUMpu71zuAFsAbwMnAZiAvWH8qsCBYXgCcGiznBdtZHY/r8XjcAYVCkTuxuCH1p6lBEuuXIrXRq1cvX7lypUtyrF271nv27Bn5+5zmUWv9qtccKzOLm9lbwCfAQmA18Jm77w02WQd0CJY7AB8CBPdvA9rW9Rz79u2rTyoiIg2SivolqVNaWsqMGTM0UpVERx5
"text/plain": [
"<Figure size 720x576 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# _, img_bin = cv.threshold(img, 100, 255, cv.THRESH_BINARY)\n",
"# _, img_bin_inv = cv.threshold(img, 100, 255, cv.THRESH_BINARY_INV)\n",
"# _, img_trunc = cv.threshold(img, 100, 255, cv.THRESH_TRUNC)\n",
"# _, img_to_zero = cv.threshold(img, 100, 255, cv.THRESH_TOZERO)\n",
"# _, img_to_zero_inv = cv.threshold(img, 100, 255, cv.THRESH_TOZERO_INV)\n",
"\n",
"image = cv.imread(\"img/road-lanes.jpg\", cv.IMREAD_GRAYSCALE)\n",
"_, image = cv.threshold(image, 210, 255, cv.THRESH_BINARY)\n",
"\n",
"plt.figure(figsize=[10,8])\n",
"plt.subplot(221)\n",
"plt.title(\"clean\")\n",
"plt.imshow(image, cmap='gray')\n",
"\n",
"rows, cols = image.shape\n",
"mask = np.zeros((rows, cols))\n",
"points = np.array([[400, 250], [650, 250], [900, 560], [100, 560]])\n",
"mask = cv.fillPoly(mask, pts=[points], color=(255, 255, 255))\n",
"rect = cv.boundingRect(points)\n",
"x,y,w,h = rect\n",
"croped = mask[y:y+h, x:x+w].copy()\n",
"\n",
"plt.subplot(222)\n",
"plt.title(\"mask\")\n",
"plt.imshow(mask, cmap='gray')\n",
"\n",
"\n",
"\n",
"# edges = cv.Canny(croped, threshold1=50, threshold2=200)\n",
"# plt.subplot(223)\n",
"# plt.title(\"edges\")\n",
"# plt.imshow(edges, cmap='gray')\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "639b0200",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x7f07f864d130>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"import math\n",
"import cv2 as cv\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"%matplotlib inline\n",
"road_rgb = cv.cvtColor(cv.imread(\"img/road-lanes.jpg\", cv.IMREAD_COLOR), cv.COLOR_BGR2RGB)\n",
"\n",
"road_gray = cv.imread(\"img/road-lanes.jpg\", cv.IMREAD_GRAYSCALE)\n",
"\n",
"_, road_bin = cv.threshold(road_gray, 210, 255, cv.THRESH_BINARY)\n",
"\n",
"rows,cols = road_bin.shape\n",
"\n",
"mask = np.zeros((rows,cols), np.uint8)\n",
"pts = np.array([[400,350],[cols-400,350],[cols,rows],[0,rows]], np.int32)\n",
"cv.fillPoly(mask, [pts], (255,255,255))\n",
"\n",
"masked_road = cv.bitwise_and(road_bin, road_bin, mask=mask)\n",
"\n",
"edges = cv.Canny(masked_road, 50, 200)\n",
"\n",
"lines = cv.HoughLinesP(masked_road, 1, np.pi / 180, 50, None, 50, 300)\n",
"\n",
"# Draw the lines\n",
"if lines is not None:\n",
" for i in range(0, len(lines)):\n",
" l = lines[i][0]\n",
" cv.line(road_rgb, (l[0], l[1]), (l[2], l[3]), (255,0,0), 3, cv.LINE_AA)\n",
"\n",
"plt.imshow(road_rgb, cmap=\"gray\")"
]
},
{
"cell_type": "markdown",
"id": "63a04ced",
"metadata": {},
"source": [
"![Pasy wykryte na drodze](img/road-lanes-detected.png)"
]
}
],
"metadata": {
"author": "Andrzej Wójtowicz",
"email": "andre@amu.edu.pl",
"kernelspec": {
"display_name": "Python 3.8.12 64-bit",
"language": "python",
"name": "python3"
},
"lang": "pl",
"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.8.12"
},
"subtitle": "04. Zaawansowane przetwarzanie obrazów i fotografia obliczeniowa [laboratoria]",
"title": "Widzenie komputerowe",
"vscode": {
"interpreter": {
"hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
}
},
"year": "2021"
},
"nbformat": 4,
"nbformat_minor": 5
}